/* A Bison parser, made by GNU Bison 1.875d.  */

/* Skeleton parser for Yacc-like parsing with Bison,
   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.

   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, 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.  */

/* As a special exception, when this file is copied by Bison into a
   Bison output file, you may use that output file without restriction.
   This special exception was added by the Free Software Foundation
   in version 1.24 of Bison.  */

/* Written by Richard Stallman by simplifying the original so called
   ``semantic'' parser.  */

/* All symbols defined below should begin with yy or YY, to avoid
   infringing on user name space.  This should be done even for local
   variables, as they might otherwise be expanded by user macros.
   There are some unavoidable exceptions within include files to
   define necessary library symbols; they are noted "INFRINGES ON
   USER NAME SPACE" below.  */

/* Identify Bison output.  */
#define YYBISON 1

/* Skeleton name.  */
#define YYSKELETON_NAME "yacc.c"

/* Pure parsers.  */
#define YYPURE 0

/* Using locations.  */
#define YYLSP_NEEDED 0

/* If NAME_PREFIX is specified substitute the variables and functions
   names.  */
#define yyparse pnparse
#define yylex   pnlex
#define yyerror pnerror
#define yylval  pnlval
#define yychar  pnchar
#define yydebug pndebug
#define yynerrs pnnerrs


/* Tokens.  */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
   /* Put the tokens into the symbol table, so that GDB and other debuggers
      know about them.  */
   enum yytokentype {
     RELEASE = 258,
     UNTIL = 259,
     EQUIV = 260,
     IMPL = 261,
     OR = 262,
     XOR = 263,
     AND = 264,
     NEXT = 265,
     GLOBALLY = 266,
     FINALLY = 267,
     EQ = 268,
     NE = 269,
     LE = 270,
     GE = 271,
     ROR = 272,
     ROL = 273,
     IS = 274,
     MAP = 275,
     MAX_ = 276,
     MIN_ = 277,
     CARDINALITY = 278,
     EQUALS = 279,
     SUBSET = 280,
     UNION = 281,
     MINUS = 282,
     INTERSECT = 283,
     ATOM_ = 284,
     NUMBER = 285,
     CHARACTER = 286,
     NAME = 287,
     TRUE_ = 288,
     FALSE_ = 289,
     UNDEFINED = 290,
     FATAL = 291,
     TYPEDEF = 292,
     CONST_ = 293,
     PLACE = 294,
     TRANS = 295,
     IN_ = 296,
     OUT_ = 297,
     GATE = 298,
     REJECT_ = 299,
     DEADLOCK = 300,
     ENUM = 301,
     ID = 302,
     STRUCT = 303,
     QUEUE = 304,
     STACK = 305,
     RANGE = 306,
     EMPTY = 307,
     SFAIR = 308,
     WFAIR = 309,
     ENABLED = 310,
     HIDE = 311,
     PROP = 312,
     SUBNET = 313
   };
#endif
#define RELEASE 258
#define UNTIL 259
#define EQUIV 260
#define IMPL 261
#define OR 262
#define XOR 263
#define AND 264
#define NEXT 265
#define GLOBALLY 266
#define FINALLY 267
#define EQ 268
#define NE 269
#define LE 270
#define GE 271
#define ROR 272
#define ROL 273
#define IS 274
#define MAP 275
#define MAX_ 276
#define MIN_ 277
#define CARDINALITY 278
#define EQUALS 279
#define SUBSET 280
#define UNION 281
#define MINUS 282
#define INTERSECT 283
#define ATOM_ 284
#define NUMBER 285
#define CHARACTER 286
#define NAME 287
#define TRUE_ 288
#define FALSE_ 289
#define UNDEFINED 290
#define FATAL 291
#define TYPEDEF 292
#define CONST_ 293
#define PLACE 294
#define TRANS 295
#define IN_ 296
#define OUT_ 297
#define GATE 298
#define REJECT_ 299
#define DEADLOCK 300
#define ENUM 301
#define ID 302
#define STRUCT 303
#define QUEUE 304
#define STACK 305
#define RANGE 306
#define EMPTY 307
#define SFAIR 308
#define WFAIR 309
#define ENABLED 310
#define HIDE 311
#define PROP 312
#define SUBNET 313




/* Copy the first part of user declarations.  */
#line 3 "maria.y"

#ifndef BSD
# ifdef __APPLE__
#  define BSD
# elif defined __FreeBSD__||defined __OpenBSD__||defined __NetBSD__
#  define BSD
# elif defined _AIX
#  define BSD
# endif
#endif
#if !defined __WIN32 && !defined __CYGWIN__ && !defined BSD
# include <alloca.h>
#endif // !__WIN32 && !__CYGWIN__ && !BSD

#include "util.h"
#include "Printer.h"
#include "VariableStackMap.h"

#include "allExpressions.h"
#include "ExpressionSet.h"
#include "Constraint.h"
#include "Range.h"

#include "Arc.h"
#include "Transition.h"
#include "Place.h"
#include "Net.h"
#include "VariableDefinition.h"
#include "VariableSet.h"
#include "Function.h"

#include "Quantifier.h"

#include "TransitionQualifier.h"

#include "allTypes.h"
#include "allValues.h"
#include "Valuation.h"

# include <set>
# include <map>
# include <list>
# include <stack>

# ifndef NDEBUG
#  define ASSERT1(x) x
# else
#  define ASSERT1(x)
# endif

  /** @file maria.y
   * Parser for the modelling language
   */

  /* Copyright © 1998-2003 Marko Mäkelä (msmakela@tcs.hut.fi).

  This file is part of MARIA, a reachability analyzer and model checker
  for high-level Petri nets.

  MARIA 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, or (at your option)
  any later version.

  MARIA 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.

  The GNU General Public License is often shipped with GNU software, and
  is generally kept in a file called COPYING or LICENSE.  If you do not
  have a copy of the license, write to the Free Software Foundation,
  59 Temple Place, Suite 330, Boston, MA 02111 USA. */

  /** warning flag (true=print warnings) */
  extern bool pnwarnings;
  /** number of errors encountered */
  extern unsigned pnerrors;
  /** Maximum index type size of arrays */
  card_t maxIndex = 256;
  /** Maximum range size of quantifications */
  card_t maxRange = 256;

  /** reset the lexical analyzer */
  extern void pnlexreset ();

  /** lexical analyzer function
   * @return		a terminal symbol, and set yylval to its semantic value
   */
  extern int pnlex ();

  /** Check the validity of an identifier
   * @param name	name of the identifier
   * @param type	type of the identifier
   * @param msg		error message
   */
  extern void checkName (const char* name, unsigned type, const char* msg);
  /** validity check codes for checkName */
  enum checkNameType {
    ckPlace = 0, ckTrans, ckType, ckEnum, ckComp,
    ckFunc, ckParam, ckVar, ckIter
  };

  /** The Petri Net */
  extern class Net* net;
# define theNet (*net)
  /** The printer object */
  extern class Printer thePrinter;
  /** Parameters of the function that is currently being processed */
  static class VariableDefinition** currentParameters = NULL;
  /** Arity of the function that is currently being processed */
  static unsigned currentArity = 0;
  /** Function being invoked */
  static std::stack< class Function*, std::list<class Function*> >
    functionStack;
  /** The place that is currently being processed */
  class Place* currentPlace = NULL;
  /** The transition that is currently being processed */
  class Transition* currentTransition = NULL;
  /** The context transition (not being processed) */
  static class Transition* currentContextTransition = NULL;
  /** The type definition that is currently being processed */
  static const class Type* currentType = NULL;
  /** The context type of currentType (StructType or VectorType or NULL) */
  static const class Type* currentContextType = NULL;
  /** Struct or vector component number currently being parsed */
  static card_t currentComponent;
  /** Type context */
  struct TypeContext
  {
    /** Context type (@see currentContextType), may be NULL */
    const class Type* context;
    /** Component type (@see currentContext) */
    const class Type* component;
    /** Number of current component (@see currentComponent)
     * , meaningless if context==NULL */
    card_t numComponent;
  };
  /** Stack of types, used e.g. when parsing quantifier conditions */
  static std::stack< struct TypeContext, std::list<struct TypeContext> >
    typeStack;
  /** Flag: is an output arc being parsed? */
  static bool isOutputArc = false;
  /** Flag: has a number been successfully parsed? */
  static bool numberParsed = false;

  /** Flag: has an empty list component been parsed? */
  static bool emptyParsed = false;

  /** type of constraint being parsed */
  static enum Net::CKind isFairnessStrong;

  typedef std::pair<const class Type*,card_t> StructLevel;
  /** Stack for parsing structs and vectors */
  static std::stack< StructLevel, std::list<StructLevel> > structLevels;

  /** check the validity of an iterator variable name
   * @param name	name of the identifier variable
   */
  static void checkIterator (const char* name);

  /** Make a copy of a type if it is not an unnamed user type
   * @param type	the type to be copied
   * @return		type or a copy of it
   */
  static class Type* copyType (class Type* type);

  /** Delete the type definition if it is an unnamed user type
   * @param type	the type to be deleted
   */
  static void deleteType (class Type* type);

  /** Display a type name in an error message
   * @param type	type to be displayed
   */
  static void printType (const class Type& type);

  /** Push the type context on structLevels
   * @param type	new type context
   */
  static void pushTypeContext (const class Type* type);
  /** Restore the type context from structLevels */
  static void popTypeContext ();

  /** Get the parameter of the currently parsed function by name
   * @param name	name of the parameter
   * @return		the corresponding VariableDefinition, or NULL
   */
  static const class VariableDefinition* getParameter (char* name);

  /** Add a parameter to the function definition being parsed
   * @param type	type of the parameter
   * @param name	name of the parameter
   */
  static void addParameter (const class Type* type, char* name);

  /** Get a Type by name
   * @param name	the type name
   * @return		a Type object
   */
  static const class Type* getType (const char* name);

  /** Get a Function by name
   * @param name	the function name
   * @return		a Function object
   */
  static class Function* getFunction (const char* name);

  /** Get a zero-arity Function by name
   * @param name	the function name
   * @return		a Function object
   */
  static class Function* getConstantFunction (const char* name);
  
  /** Get a Constant by name
   * @param name	the constant name
   * @return		a Constant object
   */
  static const class Constant* getConstant (const char* name);

  /** Get a VariableDefinition by name
   * @param name	the variable name
   * @return		a VariableDefinition object
   */
  static const class VariableDefinition* getVariable (char* name);

  /** Resolve a name to a constant or variable
   * @param name	the name
   * @return		the resolved expression, or NULL
   */
  static class Expression* resolveName (char* name);

  /** Ensure that the formula is a set-valued expression
   * @param expr	formula to be checked
   * @param type	expected type of the formula
   * @return		expr, pointer to a Marking object, or NULL
   */
  static class Expression* ensureSet (class Expression* expr,
				      const class Type* type = 0);

  /** Ensure that the formula is a marking expression, converting if needed
   * @param expr	formula to be checked
   * @param type	expected type of the expression
   * @param temporal	flag: allow expr to be temporal
   * @return		pointer to a Marking object, or NULL
   */
  static class Marking* ensureMarking (class Expression* expr,
				       const class Type* type,
				       bool temporal = false);

  /** Ensure that the formula is not a marking expression
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* noMarking (class Expression* expr);

  /** Ensure that the formula is a basic expression
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* ensureExpr (class Expression* expr);

  /** Ensure that the formula is a boolean expression
   * @param expr	formula to be checked
   * @param undefined	flag: allow the formula to be Undefined
   * @return		expr or NULL
   */
  static class Expression* ensureBool (class Expression* expr,
				       bool undefined = false);

  /** Ensure that the formula is a signed integer expression
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* ensureInt (class Expression* expr);

  /** Ensure that the formula is an unsigned integer expression
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* ensureCard (class Expression* expr);

  /** Ensure that the formula is a signed or unsigned integer expression
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* ensureIntCard (class Expression* expr);

  /** Ensure that the formula is a buffer expression
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* ensureBuffer (class Expression* expr);

  /** Ensure that the formula is a basic expression of ordered type
   * @param expr	formula to be checked
   * @return		expr or NULL
   */
  static class Expression* ensureOrdered (class Expression* expr);

  /** Add an enumeration constant to an enumerated type, ensuring uniqueness.
   * @param e		the enumeration type
   * @param name	name of the constant
   */
  static void addEnumeration (class EnumType* e, char* name);

  /** Add an enumeration constant to an enumerated type, ensuring uniqueness.
   * @param e		the enumeration type
   * @param name	name of the constant
   * @param value	value of the constant
   */
  static void addEnumeration (class EnumType* e, char* name, card_t value);

  /** Ensure that the formula is a constant literal
   * @param expr	formula to be checked
   * @param type	type of the constant expected
   * @return		the value of expr or NULL
   */
  static class Value* ensureConstant (class Expression* expr,
				      const class Type* type);

  /** Convert an integer to an enumeration value if possible
   * @param type	type of the enumeration value
   * @param value	numerical value to be converted to the enumeration type
   * @return		a constant having the enumeration value or NULL
   */
  static class Expression* enumValue (const class EnumType& type,
				      card_t value);

  /** Ensure that a named component matches a struct being parsed
   * @param name	name of the component
   * @param expr	initialization expression for the component
   * @return		expr or NULL
   */
  static class Expression* namedComponent (char* name, class Expression* expr);

  /** Begin parsing a non-determinism expression
   * @param type	type of the expression
   * @param hidden	flag: hide the variable from transition instances
   * @param name	name of the non-deterministic variable (optional)
   */
  static void beginAny (class Type*& type, char* name, bool hidden);

  /** End parsing a non-determinisim expression
   * @param type	type of the expression
   * @param name	name of the non-deterministic variable (optional)
   * @param condition	quantification condition (optional)
   * @return		a Variable expression for the variable, or NULL
   */
  static class Variable* endAny (const class Type* type, char* name,
				 class Expression* condition);

  /** Begin parsing a quantifier expression
   * @param name	name of the quantifier variable
   * @param type	type of the quantifier variable
   */
  static void beginQuantifier (char* name, const class Type* type);

  /** Continue parsing a quantifier expression
   *  (after parsing an optional condition)
   * @param type	type of the quantifier variable
   */
  static void continueQuantifier (ASSERT1 (const class Type* type));

  /** End parsing a quantifier expression
   * @param name	name of the quantifier variable
   * @param type	type of the quantifier variable
   * @param condition	quantification condition (optional)
   * @param kind	quantification kind (1=sum, 2=forall, 3=exists)
   * @param expr	expression
   * @param temporal	flag: allow expr to be temporal
   * @return		expr augmented with the quantifier, or NULL if failed
   */
  static class Expression* endQuantifier (char* name, const class Type* type,
					  class Expression* condition,
					  unsigned kind,
					  class Expression* expr,
					  bool temporal);

  /** Declare a quantified variable
   * @param prefix	prefix of the quantified variable
   * @param quant	name of the quantifier variable
   * @param p		flag: use a predecessor value of the quantifier
   * @return		a quantified variable, or NULL if failed
   */
  static class Expression* quantifierVariable (char* prefix,
					       char* quant,
					       bool p);

  /** Try to make expr compatible with type if expr is a Constant
   * @param expr	expression to be made compatible
   * @param type	type to be made compatible with
   * @param casting	flag: typecasting in progress (suppress a warning)
   * @return		true if expr is not a Constant or
   *			if the conversion succeeded
   */
  static bool makeCompatible (class Expression*& expr,
			      const class Type& type,
			      bool casting = false);

  /** Determine whether an expression is compatible with a type
   * @param expr	expression to be checked
   * @param type	the type
   * @return		true if the expression is compatible with the type
   */
  static bool isCompatible (class Expression*& expr,
			    const class Type* type);

  /** Determine whether an expression is compatible with
   * the struct component being parsed
   * @param expr	expression to be checked
   * @param s		the struct whose current component is considered
   * @return		true if the expression is compatible with the struct
   */
  static bool isCompatible (class Expression*& expr,
			    const class StructExpression& s);

  /** Ensure that the type is ordered
   * @param type	type to be checked
   * @return		true if the type is ordered
   */
  static bool isOrdered (const class Type& type);

  /** Check a valuation
   * @param v		valuation to be checked
   * @return		true if the valuation is OK
   */
  static bool check (const class Valuation& v);

  /** Perform constant folding
   * @param expr	expression to be folded
   * @return		expr or a new Constant, or NULL in case of error
   */
  static class Expression* fold (class Expression* expr);

  /** Define a function
   * @param type	type of the function
   * @param name	name of the function
   * @param expr	body of the function
   */
  static void defun (const class Type* type,
		     char* name,
		     class Expression* expr);

  /** Create a RelopExpression or optimize it
   * @param equal	flag: equality comparison (instead of less-than)
   * @param left	left-hand-side of RelopExpression
   * @param right	right-hand-side of RelopExpression
   * @return		RelopExpression or a Boolean constant
   */
  static class Expression* newRelopExpression (bool equal,
					       class Expression* left,
					       class Expression* right);

  /** Create a BinopExpression
   * @param op		operator
   * @param left	left-hand-side of BinopExpression
   * @param right	right-hand-side of BinopExpression
   * @return		BinopExpression
   */
  static class Expression* newBinopExpression (enum BinopExpression::Op op,
					       class Expression* left,
					       class Expression* right);

  /** Create a NotExpression or optimize it
   * @param expr	an expression
   * @return		a negation of the expression
   */
  static class Expression* newNotExpression (class Expression* expr);

  /** Create a BooleanBinop or optimize it
   * @param conj	flag: conjunction (instead of disjunction)
   * @param left	left-hand-side of BooleanBinop
   * @param right	right-hand-side of BooleanBinop
   * @return		left, right, Boolean constant, or a BooleanBinop
   */
  static class Expression* newBooleanBinop (bool conj,
					    class Expression* left,
					    class Expression* right);

  /** Create a SetExpression or optimize it
   * @param op		operator
   * @param left	left-hand-side of SetExpression
   * @param right	right-hand-side of SetExpression
   */
  static class Expression* newSetExpression (enum SetExpression::Op op,
					     class Expression* left,
					     class Expression* right);
  /** Create a CardinalityExpression or optimize it
   * @param op		operator
   * @param expr	the multi-set expression
   */
  static class Expression* newCardinalityExpression
    (enum CardinalityExpression::Op op,
     class Expression* expr);

  /** Create a BufferUnop from a buffer expression
   * @param op		operator
   * @param expr	the buffer expression
   * @return		a BufferUnop object, or NULL
   */
  static class Expression* newBufferUnop (enum BufferUnop::Op op,
					  class Expression* expr);

  /** Variable stack map to be used with variable scoping */
  static class VariableStackMap currentVariables;

  /**
   * generic compiler warning reporting function
   * @param s		warning message
   */
  extern void pnwarn (const char* s);

  /**
   * generic parser error reporting function
   * @param s		error message
   */
  extern void pnerror (const char* s);


/* Enabling traces.  */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif

/* Enabling verbose error messages.  */
#ifdef YYERROR_VERBOSE
# undef YYERROR_VERBOSE
# define YYERROR_VERBOSE 1
#else
# define YYERROR_VERBOSE 0
#endif

#if ! defined (YYSTYPE) && ! defined (YYSTYPE_IS_DECLARED)
#line 523 "maria.y"
typedef union YYSTYPE {
  card_t i;
  bool flag;
  char_t c;
  char* s;
  class Expression* expr;
  class ExpressionList* exprList;
  class Transition* trans;
  class Place* place;
  class Marking* marking;
  class Type* type;
  class ComponentList* componentList;
  class Value* value;
  class Range* range;
  class Constraint* constraint;
} YYSTYPE;
/* Line 191 of yacc.c.  */
#line 738 "maria.tab.c"
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif



/* Copy the second part of user declarations.  */


/* Line 214 of yacc.c.  */
#line 750 "maria.tab.c"

#if ! defined (yyoverflow) || YYERROR_VERBOSE

# ifndef YYFREE
#  define YYFREE free
# endif
# ifndef YYMALLOC
#  define YYMALLOC malloc
# endif

/* The parser invokes alloca or malloc; define the necessary symbols.  */

# ifdef YYSTACK_USE_ALLOCA
#  if YYSTACK_USE_ALLOCA
#   define YYSTACK_ALLOC alloca
#  endif
# else
#  if defined (alloca) || defined (_ALLOCA_H)
#   define YYSTACK_ALLOC alloca
#  else
#   ifdef __GNUC__
#    define YYSTACK_ALLOC __builtin_alloca
#   endif
#  endif
# endif

# ifdef YYSTACK_ALLOC
   /* Pacify GCC's `empty if-body' warning. */
#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
# else
#  if defined (__STDC__) || defined (__cplusplus)
#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
#   define YYSIZE_T size_t
#  endif
#  define YYSTACK_ALLOC YYMALLOC
#  define YYSTACK_FREE YYFREE
# endif
#endif /* ! defined (yyoverflow) || YYERROR_VERBOSE */


#if (! defined (yyoverflow) \
     && (! defined (__cplusplus) \
	 || (defined (YYSTYPE_IS_TRIVIAL) && YYSTYPE_IS_TRIVIAL)))

/* A type that is properly aligned for any stack member.  */
union yyalloc
{
  short int yyss;
  YYSTYPE yyvs;
  };

/* The size of the maximum gap between one aligned stack and the next.  */
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)

/* The size of an array large to enough to hold all stacks, each with
   N elements.  */
# define YYSTACK_BYTES(N) \
     ((N) * (sizeof (short int) + sizeof (YYSTYPE))			\
      + YYSTACK_GAP_MAXIMUM)

/* Copy COUNT objects from FROM to TO.  The source and destination do
   not overlap.  */
# ifndef YYCOPY
#  if defined (__GNUC__) && 1 < __GNUC__
#   define YYCOPY(To, From, Count) \
      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
#  else
#   define YYCOPY(To, From, Count)		\
      do					\
	{					\
	  register YYSIZE_T yyi;		\
	  for (yyi = 0; yyi < (Count); yyi++)	\
	    (To)[yyi] = (From)[yyi];		\
	}					\
      while (0)
#  endif
# endif

/* Relocate STACK from its old location to the new one.  The
   local variables YYSIZE and YYSTACKSIZE give the old and new number of
   elements in the stack, and YYPTR gives the new location of the
   stack.  Advance YYPTR to a properly aligned location for the next
   stack.  */
# define YYSTACK_RELOCATE(Stack)					\
    do									\
      {									\
	YYSIZE_T yynewbytes;						\
	YYCOPY (&yyptr->Stack, Stack, yysize);				\
	Stack = &yyptr->Stack;						\
	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
	yyptr += yynewbytes / sizeof (*yyptr);				\
      }									\
    while (0)

#endif

#if defined (__STDC__) || defined (__cplusplus)
   typedef signed char yysigned_char;
#else
   typedef short int yysigned_char;
#endif

/* YYFINAL -- State number of the termination state. */
#define YYFINAL  81
/* YYLAST -- Last index in YYTABLE.  */
#define YYLAST   1950

/* YYNTOKENS -- Number of terminals. */
#define YYNTOKENS  84
/* YYNNTS -- Number of nonterminals. */
#define YYNNTS  106
/* YYNRULES -- Number of rules. */
#define YYNRULES  288
/* YYNRULES -- Number of states. */
#define YYNSTATES  466

/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
#define YYUNDEFTOK  2
#define YYMAXUTOK   313

#define YYTRANSLATE(YYX) 						\
  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)

/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
static const unsigned char yytranslate[] =
{
       0,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,    34,     2,    31,     2,    30,    17,     2,
      47,    81,    28,    26,    83,    27,    45,    29,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     4,    77,
      20,    82,    21,     3,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,    46,     2,    80,    16,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,    78,    15,    79,    33,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     2,     2,     2,     2,     2,     1,     2,     5,     6,
       7,     8,     9,    10,    11,    12,    13,    14,    18,    19,
      22,    23,    24,    25,    32,    35,    36,    37,    38,    39,
      40,    41,    42,    43,    44,    48,    49,    50,    51,    52,
      53,    54,    55,    56,    57,    58,    59,    60,    61,    62,
      63,    64,    65,    66,    67,    68,    69,    70,    71,    72,
      73,    74,    75,    76
};

#if YYDEBUG
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
   YYRHS.  */
static const unsigned short int yyprhs[] =
{
       0,     0,     3,     5,     6,     8,    10,    13,    16,    20,
      22,    24,    26,    28,    30,    32,    34,    36,    40,    42,
      44,    47,    50,    55,    60,    65,    70,    72,    73,    77,
      82,    88,    93,    97,   101,   103,   105,   108,   112,   115,
     117,   119,   121,   123,   125,   127,   128,   130,   131,   133,
     135,   136,   138,   139,   141,   145,   149,   155,   157,   159,
     161,   164,   169,   172,   173,   175,   177,   179,   180,   186,
     187,   195,   198,   203,   206,   207,   208,   209,   213,   214,
     217,   218,   226,   228,   229,   233,   234,   237,   238,   241,
     242,   249,   252,   253,   258,   259,   264,   265,   270,   271,
     276,   277,   282,   283,   288,   293,   296,   297,   299,   303,
     306,   310,   311,   318,   321,   322,   325,   329,   331,   335,
     336,   339,   340,   346,   347,   350,   353,   355,   358,   361,
     362,   365,   368,   370,   373,   376,   378,   382,   384,   387,
     390,   395,   396,   403,   408,   409,   413,   415,   417,   419,
     422,   425,   428,   430,   434,   436,   438,   440,   444,   446,
     447,   452,   453,   457,   458,   460,   463,   467,   469,   473,
     474,   476,   478,   480,   482,   484,   486,   488,   491,   492,
     498,   500,   502,   505,   507,   509,   511,   513,   515,   516,
     521,   522,   527,   528,   533,   537,   540,   541,   546,   547,
     553,   557,   561,   565,   569,   573,   577,   581,   585,   589,
     593,   597,   600,   603,   606,   609,   612,   615,   618,   621,
     624,   627,   631,   635,   639,   643,   647,   651,   652,   653,
     664,   665,   673,   677,   678,   684,   687,   691,   695,   699,
     703,   707,   710,   713,   716,   720,   724,   726,   730,   734,
     738,   742,   746,   749,   752,   755,   759,   763,   764,   765,
     773,   777,   781,   782,   790,   791,   799,   800,   810,   811,
     812,   815,   816,   821,   824,   826,   830,   831,   832,   840,
     841,   846,   848,   852,   855,   859,   863,   867,   871
};

/* YYRHS -- A `-1'-separated list of the rules' RHS. */
static const short int yyrhs[] =
{
      85,     0,    -1,    86,    -1,    -1,    87,    -1,    77,    -1,
      87,    77,    -1,    88,    77,    -1,    87,    88,    77,    -1,
      89,    -1,   111,    -1,   118,    -1,   124,    -1,   151,    -1,
     147,    -1,   148,    -1,   149,    -1,    55,    91,   102,    -1,
      67,    -1,    68,    -1,    90,    67,    -1,    90,    68,    -1,
      64,    78,   105,    79,    -1,    65,    46,    99,    80,    -1,
      66,    78,   108,    79,    -1,    41,    78,   108,    79,    -1,
      98,    -1,    -1,    91,    92,    93,    -1,    91,    46,    91,
      80,    -1,    91,    46,    90,    99,    80,    -1,    91,    46,
      48,    80,    -1,    47,    94,    81,    -1,    94,   106,    95,
      -1,    95,    -1,    97,    -1,    69,    97,    -1,    96,    69,
      96,    -1,    96,    69,    -1,   164,    -1,   163,    -1,   100,
      -1,   164,    -1,    50,    -1,     1,    -1,    -1,   100,    -1,
      -1,   100,    -1,   100,    -1,    -1,    82,    -1,    -1,   103,
      -1,   105,   106,   103,    -1,   103,   104,    99,    -1,   105,
     106,   103,   104,    99,    -1,    77,    -1,    83,    -1,   102,
      -1,    91,   107,    -1,   108,   106,    91,   107,    -1,   108,
     106,    -1,    -1,    12,    -1,    82,    -1,   102,    -1,    -1,
      98,   110,   109,   112,   166,    -1,    -1,    98,   110,    47,
     114,    81,   113,   166,    -1,    98,   102,    -1,   114,   106,
      98,   102,    -1,   114,   106,    -1,    -1,    -1,    -1,   115,
     116,    93,    -1,    -1,   117,    56,    -1,    -1,   142,   100,
     115,    91,   117,   119,   121,    -1,   102,    -1,    -1,   121,
       4,   157,    -1,    -1,   122,     4,    -1,    -1,   123,    34,
      -1,    -1,   144,   122,   100,   123,   125,   127,    -1,   144,
     102,    -1,    -1,   127,    78,   133,    79,    -1,    -1,   127,
      59,   128,   137,    -1,    -1,   127,    60,   129,   137,    -1,
      -1,   127,    61,   130,   145,    -1,    -1,   127,   153,   131,
     166,    -1,    -1,   127,    74,   132,   164,    -1,   127,     4,
     143,   102,    -1,   127,    48,    -1,    -1,   134,    -1,   133,
     106,   134,    -1,   133,   106,    -1,   136,    98,   102,    -1,
      -1,   136,    98,   100,    34,   135,   160,    -1,   136,   111,
      -1,    -1,   136,    74,    -1,    78,   138,    79,    -1,   139,
      -1,   138,    77,   139,    -1,    -1,   141,     1,    -1,    -1,
     141,   120,     4,   140,   157,    -1,    -1,   141,    57,    -1,
     141,    58,    -1,    57,    -1,   142,    57,    -1,   142,    58,
      -1,    -1,   141,    58,    -1,   141,    57,    -1,    58,    -1,
     144,    58,    -1,   144,    57,    -1,   146,    -1,   145,    83,
     146,    -1,   164,    -1,    62,   164,    -1,    63,   164,    -1,
      75,   102,     4,   164,    -1,    -1,    76,   101,    78,   150,
      87,    79,    -1,    76,   101,    78,    79,    -1,    -1,   153,
     152,   154,    -1,    72,    -1,    71,    -1,    73,    -1,   153,
      72,    -1,   153,    71,    -1,   153,    73,    -1,   155,    -1,
     154,    83,   155,    -1,   186,    -1,   166,    -1,   156,    -1,
     157,    83,   156,    -1,   166,    -1,    -1,   158,    83,   159,
     156,    -1,    -1,    47,   163,    81,    -1,    -1,   164,    -1,
      50,     4,    -1,    50,     4,   164,    -1,   161,    -1,   162,
      83,   161,    -1,    -1,   164,    -1,   166,    -1,     1,    -1,
       4,    -1,     9,    -1,    11,    -1,     1,    -1,   100,    12,
      -1,    -1,   100,    47,   167,   182,    81,    -1,    51,    -1,
      52,    -1,   142,   120,    -1,    50,    -1,    48,    -1,    49,
      -1,    53,    -1,    54,    -1,    -1,    78,   168,   162,    79,
      -1,    -1,    32,    98,   169,   166,    -1,    -1,   100,    82,
     170,   166,    -1,   166,    32,   102,    -1,    44,   166,    -1,
      -1,    98,    34,   171,   160,    -1,    -1,    98,   100,    34,
     172,   160,    -1,   166,    20,   166,    -1,   166,    18,   166,
      -1,   166,    21,   166,    -1,   166,    23,   166,    -1,   166,
      19,   166,    -1,   166,    22,   166,    -1,   166,    26,   166,
      -1,   166,    27,   166,    -1,   166,    29,   166,    -1,   166,
      28,   166,    -1,   166,    30,   166,    -1,    33,   166,    -1,
      31,    98,    -1,    20,    98,    -1,    21,    98,    -1,    15,
     166,    -1,    26,   166,    -1,    27,   166,    -1,    28,   166,
      -1,    29,   166,    -1,    30,   166,    -1,   166,    25,   166,
      -1,   166,    24,   166,    -1,   166,    17,   166,    -1,   166,
      16,   166,    -1,   166,    15,   166,    -1,   166,     3,   185,
      -1,    -1,    -1,   166,    45,    78,    46,   173,   163,    80,
     174,   163,    79,    -1,    -1,   166,    45,    78,   100,   175,
     163,    79,    -1,   166,    45,   100,    -1,    -1,   166,    46,
     176,   164,    80,    -1,    34,   166,    -1,   166,    11,   166,
      -1,   166,     9,   166,    -1,   166,     8,   166,    -1,   166,
      10,   166,    -1,   166,     7,   166,    -1,    14,   166,    -1,
      13,   166,    -1,    12,   166,    -1,   166,     6,   166,    -1,
     166,     5,   166,    -1,    70,    -1,   166,    40,   166,    -1,
     166,    43,   166,    -1,   166,    42,   166,    -1,   166,    41,
     166,    -1,   166,    39,   166,    -1,    38,   166,    -1,    37,
     166,    -1,    36,   166,    -1,    47,   158,    81,    -1,   166,
      31,   166,    -1,    -1,    -1,    98,   100,   177,   160,   178,
     165,   166,    -1,    45,   100,   101,    -1,     4,   100,   101,
      -1,    -1,    40,   102,    78,   158,    79,   179,   166,    -1,
      -1,    35,   102,    78,   158,    79,   180,   166,    -1,    -1,
      35,   102,    31,   102,    78,   158,    79,   181,   166,    -1,
      -1,    -1,   183,   166,    -1,    -1,   182,    83,   184,   166,
      -1,   182,    83,    -1,   166,    -1,   185,     4,   166,    -1,
      -1,    -1,    98,   100,   187,   160,   188,   165,   186,    -1,
      -1,   126,     4,   189,   166,    -1,   126,    -1,    47,   186,
      81,    -1,    34,   186,    -1,   186,    11,   186,    -1,   186,
       9,   186,    -1,   186,     8,   186,    -1,   186,    10,   186,
      -1,   186,     7,   186,    -1
};

/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
static const unsigned short int yyrline[] =
{
       0,   649,   649,   655,   657,   660,   663,   666,   668,   672,
     674,   676,   678,   680,   682,   684,   686,   690,   710,   713,
     716,   719,   724,   730,   741,   744,   756,   760,   759,   781,
     807,   823,   831,   836,   844,   849,   852,   855,   867,   872,
     877,   882,   905,   959,   962,   967,   969,   974,   976,   981,
     988,   990,   994,   996,  1006,  1016,  1027,  1041,  1041,  1044,
    1052,  1067,  1096,  1104,  1108,  1110,  1114,  1123,  1122,  1128,
    1127,  1139,  1147,  1155,  1162,  1166,  1169,  1168,  1189,  1191,
    1197,  1196,  1231,  1248,  1250,  1261,  1263,  1268,  1270,  1276,
    1275,  1350,  1367,  1369,  1372,  1371,  1376,  1375,  1380,  1379,
    1385,  1384,  1402,  1401,  1412,  1430,  1442,  1444,  1447,  1454,
    1463,  1497,  1496,  1501,  1506,  1508,  1513,  1517,  1519,  1522,
    1524,  1528,  1527,  1559,  1561,  1564,  1569,  1571,  1574,  1579,
    1581,  1584,  1589,  1591,  1594,  1599,  1601,  1605,  1637,  1640,
    1645,  1665,  1664,  1685,  1691,  1690,  1697,  1700,  1703,  1706,
    1709,  1712,  1717,  1719,  1723,  1731,  1736,  1739,  1749,  1753,
    1752,  1765,  1767,  1772,  1774,  1777,  1780,  1785,  1850,  1940,
    1942,  1947,  1952,  1955,  1958,  1961,  1966,  1969,  1991,  1990,
    2020,  2026,  2032,  2035,  2038,  2044,  2050,  2053,  2057,  2056,
    2189,  2188,  2206,  2205,  2267,  2302,  2306,  2305,  2311,  2310,
    2315,  2318,  2321,  2324,  2327,  2330,  2333,  2357,  2376,  2379,
    2382,  2385,  2391,  2408,  2416,  2424,  2430,  2436,  2455,  2458,
    2461,  2464,  2467,  2470,  2473,  2476,  2479,  2510,  2523,  2509,
    2547,  2546,  2589,  2639,  2638,  2694,  2697,  2707,  2717,  2727,
    2733,  2736,  2744,  2752,  2760,  2771,  2782,  2785,  2788,  2791,
    2794,  2797,  2800,  2803,  2806,  2809,  2812,  2868,  2870,  2867,
    2874,  2877,  2881,  2880,  2931,  2930,  2985,  2984,  3038,  3057,
    3057,  3091,  3090,  3128,  3134,  3142,  3166,  3168,  3165,  3173,
    3172,  3184,  3194,  3197,  3200,  3209,  3218,  3227,  3230
};
#endif

#if YYDEBUG || YYERROR_VERBOSE
/* YYTNME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
   First, the terminals, then, starting at YYNTOKENS, nonterminals. */
static const char *const yytname[] =
{
  "$end", "error", "$undefined", "'?'", "':'", "RELEASE", "UNTIL",
  "EQUIV", "IMPL", "OR", "XOR", "AND", "NEXT", "GLOBALLY", "FINALLY",
  "'|'", "'^'", "'&'", "EQ", "NE", "'<'", "'>'", "LE", "GE", "ROR", "ROL",
  "'+'", "'-'", "'*'", "'/'", "'%'", "'#'", "IS", "'~'", "'!'", "MAP",
  "MAX_", "MIN_", "CARDINALITY", "EQUALS", "SUBSET", "UNION", "MINUS",
  "INTERSECT", "ATOM_", "'.'", "'['", "'('", "NUMBER", "CHARACTER", "NAME",
  "TRUE_", "FALSE_", "UNDEFINED", "FATAL", "TYPEDEF", "CONST_", "PLACE",
  "TRANS", "IN_", "OUT_", "GATE", "REJECT_", "DEADLOCK", "ENUM", "ID",
  "STRUCT", "QUEUE", "STACK", "RANGE", "EMPTY", "SFAIR", "WFAIR",
  "ENABLED", "HIDE", "PROP", "SUBNET", "';'", "'{'", "'}'", "']'", "')'",
  "'='", "','", "$accept", "start", "_opt_net", "net", "netcomponent",
  "type", "queue_stack", "typedefinition", "@1", "constraint",
  "range_list", "range", "value", "value_", "typereference", "number",
  "name_", "_opt_name", "name", "enum_name", "_opt_eq", "enum_list",
  "delim", "comp_name", "comp_list", "next_eq", "func_name", "function",
  "@2", "@3", "param_list", "_opt_capacity", "@4", "_opt_const", "place",
  "@5", "placename", "place_init", "_opt_colon", "_opt_exclam",
  "transition", "@6", "transname", "trans", "@7", "@8", "@9", "@10", "@11",
  "_list_var_expr", "var_expr", "@12", "_opt_hide", "trans_places",
  "_list_place_marking", "place_marking", "@13", "_opt_place",
  "_nopt_place", "_opt_trans", "_nopt_trans", "gate_list", "gate",
  "verify", "prop", "subnet", "@14", "fairness", "@15", "fairness_strong",
  "fair", "fair_expr", "marking", "marking_list", "marking_list_", "@16",
  "_opt_expr", "_opt__expr", "struct_expr", "expr_", "expr", "quantifier",
  "formula", "@17", "@18", "@19", "@20", "@21", "@22", "@23", "@24", "@25",
  "@26", "@27", "@28", "@29", "@30", "@31", "arg_list", "@32", "@33",
  "colon_formula", "qual_expr", "@34", "@35", "@36", 0
};
#endif

# ifdef YYPRINT
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
   token YYLEX-NUM.  */
static const unsigned short int yytoknum[] =
{
       0,   256,   257,    63,    58,   258,   259,   260,   261,   262,
     263,   264,   265,   266,   267,   124,    94,    38,   268,   269,
      60,    62,   270,   271,   272,   273,    43,    45,    42,    47,
      37,    35,   274,   126,    33,   275,   276,   277,   278,   279,
     280,   281,   282,   283,   284,    46,    91,    40,   285,   286,
     287,   288,   289,   290,   291,   292,   293,   294,   295,   296,
     297,   298,   299,   300,   301,   302,   303,   304,   305,   306,
     307,   308,   309,   310,   311,   312,   313,    59,   123,   125,
      93,    41,    61,    44
};
# endif

/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
static const unsigned char yyr1[] =
{
       0,    84,    85,    86,    86,    87,    87,    87,    87,    88,
      88,    88,    88,    88,    88,    88,    88,    89,    90,    90,
      90,    90,    91,    91,    91,    91,    91,    92,    91,    91,
      91,    91,    93,    94,    94,    95,    95,    95,    95,    96,
      97,    98,    99,   100,   100,   101,   101,   102,   102,   103,
     104,   104,   105,   105,   105,   105,   105,   106,   106,   107,
     108,   108,   108,   108,   109,   109,   110,   112,   111,   113,
     111,   114,   114,   114,   114,   115,   116,   115,   117,   117,
     119,   118,   120,   121,   121,   122,   122,   123,   123,   125,
     124,   126,   127,   127,   128,   127,   129,   127,   130,   127,
     131,   127,   132,   127,   127,   127,   133,   133,   133,   133,
     134,   135,   134,   134,   136,   136,   137,   138,   138,   139,
     139,   140,   139,   141,   141,   141,   142,   142,   142,   143,
     143,   143,   144,   144,   144,   145,   145,   146,   147,   147,
     148,   150,   149,   149,   152,   151,   153,   153,   153,   153,
     153,   153,   154,   154,   155,   156,   157,   157,   158,   159,
     158,   160,   160,   161,   161,   161,   161,   162,   162,   163,
     163,   164,   165,   165,   165,   165,   166,   166,   167,   166,
     166,   166,   166,   166,   166,   166,   166,   166,   168,   166,
     169,   166,   170,   166,   166,   166,   171,   166,   172,   166,
     166,   166,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   166,   173,   174,   166,
     175,   166,   166,   176,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   166,   177,   178,   166,
     166,   166,   179,   166,   180,   166,   181,   166,   182,   183,
     182,   184,   182,   182,   185,   185,   187,   188,   186,   189,
     186,   186,   186,   186,   186,   186,   186,   186,   186
};

/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
static const unsigned char yyr2[] =
{
       0,     2,     1,     0,     1,     1,     2,     2,     3,     1,
       1,     1,     1,     1,     1,     1,     1,     3,     1,     1,
       2,     2,     4,     4,     4,     4,     1,     0,     3,     4,
       5,     4,     3,     3,     1,     1,     2,     3,     2,     1,
       1,     1,     1,     1,     1,     0,     1,     0,     1,     1,
       0,     1,     0,     1,     3,     3,     5,     1,     1,     1,
       2,     4,     2,     0,     1,     1,     1,     0,     5,     0,
       7,     2,     4,     2,     0,     0,     0,     3,     0,     2,
       0,     7,     1,     0,     3,     0,     2,     0,     2,     0,
       6,     2,     0,     4,     0,     4,     0,     4,     0,     4,
       0,     4,     0,     4,     4,     2,     0,     1,     3,     2,
       3,     0,     6,     2,     0,     2,     3,     1,     3,     0,
       2,     0,     5,     0,     2,     2,     1,     2,     2,     0,
       2,     2,     1,     2,     2,     1,     3,     1,     2,     2,
       4,     0,     6,     4,     0,     3,     1,     1,     1,     2,
       2,     2,     1,     3,     1,     1,     1,     3,     1,     0,
       4,     0,     3,     0,     1,     2,     3,     1,     3,     0,
       1,     1,     1,     1,     1,     1,     1,     2,     0,     5,
       1,     1,     2,     1,     1,     1,     1,     1,     0,     4,
       0,     4,     0,     4,     3,     2,     0,     4,     0,     5,
       3,     3,     3,     3,     3,     3,     3,     3,     3,     3,
       3,     2,     2,     2,     2,     2,     2,     2,     2,     2,
       2,     3,     3,     3,     3,     3,     3,     0,     0,    10,
       0,     7,     3,     0,     5,     2,     3,     3,     3,     3,
       3,     2,     2,     2,     3,     3,     1,     3,     3,     3,
       3,     3,     2,     2,     2,     3,     3,     0,     0,     7,
       3,     3,     0,     7,     0,     7,     0,     9,     0,     0,
       2,     0,     4,     2,     1,     3,     0,     0,     7,     0,
       4,     1,     3,     2,     3,     3,     3,     3,     3
};

/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
   means the default is an error.  */
static const unsigned short int yydefact[] =
{
       0,    44,    43,     0,   126,   132,     0,     0,   147,   146,
     148,     0,     0,     5,     0,     2,     0,     0,     9,     0,
      41,    10,    11,    12,     0,    85,    14,    15,    16,    13,
     144,     0,     0,     0,     0,     0,    26,   176,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,   184,   185,   183,   180,   181,   186,   187,   246,
     188,     0,    41,     0,   138,   171,   139,    48,     0,    46,
       0,     1,     6,     0,     7,    66,     0,   127,   128,    75,
     134,   133,     0,   150,   149,   151,     0,     0,     0,     0,
       0,     0,     0,    17,     0,   243,   242,   241,   215,   213,
     214,   216,   217,   218,   219,   220,   212,   190,   211,   235,
       0,   254,   253,   252,     0,   195,     0,     0,   158,     0,
     196,   257,   177,   178,   192,    82,   182,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     0,     0,     0,     0,   233,
       0,   141,     8,    64,     0,    65,    67,     0,    86,    87,
       0,     0,     0,   281,     0,   145,   152,   154,     0,     0,
      49,    50,     0,     0,    42,     0,     0,    18,    19,     0,
      27,     0,    28,   261,     0,     0,     0,     0,   260,   255,
     159,   183,   167,     0,   164,   161,   198,   161,   269,     0,
     274,   226,   245,   244,   240,   238,   237,   239,   236,   225,
     224,   223,   201,   204,   200,   202,   205,   203,   222,   221,
     206,   207,   209,   208,   210,   256,   194,   251,   247,   250,
     249,   248,     0,   232,     0,   140,   143,     0,     0,     0,
       0,    78,     0,    89,   283,     0,   276,   279,    91,     0,
       0,     0,     0,     0,     0,    59,    60,    57,    25,    58,
       0,    51,     0,    22,     0,    23,    24,    31,    20,    21,
       0,    29,     0,     0,    34,     0,    35,    40,   170,   191,
       0,     0,     0,     0,     0,   189,     0,     0,   197,   161,
     258,     0,     0,   193,     0,   227,   230,     0,     0,    71,
      69,     0,    68,    80,    77,    88,    92,   282,   161,     0,
     153,   288,   286,   285,   287,   284,     0,    55,    50,    30,
      36,   170,    32,     0,     0,     0,   264,   262,   160,   155,
     166,   168,     0,   199,     0,   179,   271,   270,   275,     0,
       0,   234,   142,     0,     0,    79,    83,    90,   277,   280,
      61,     0,    33,    37,    39,     0,     0,     0,   162,   172,
     173,   174,   175,     0,     0,     0,     0,    70,    72,    81,
     129,   105,    94,    96,    98,   102,   106,   100,     0,    56,
     266,   265,   263,   259,   272,   228,   231,     0,     0,     0,
       0,     0,     0,     0,     0,   107,     0,     0,     0,     0,
       0,   156,    84,   131,   130,   104,   123,    95,    97,    99,
     135,   137,   103,    93,   109,   115,     0,   113,   101,   278,
     267,     0,     0,     0,   117,     0,     0,   108,    48,    66,
     229,   157,   123,   116,   120,   124,   125,     0,   136,   111,
     118,   121,   161,     0,   112,   122
};

/* YYDEFGOTO[NTERM-NUM]. */
static const short int yydefgoto[] =
{
      -1,    14,    15,    16,    17,    18,   199,   188,   102,   202,
     293,   294,   295,   296,    71,   193,    72,    80,   135,   191,
     282,   192,   280,   276,   189,   176,    86,    21,   260,   363,
     259,   177,   262,   323,    22,   366,   136,   389,    92,   263,
      23,   326,   183,   367,   410,   411,   412,   417,   413,   414,
     415,   462,   416,   427,   443,   444,   463,   445,    73,   409,
     184,   429,   430,    26,    27,    28,   257,    29,    96,    30,
     185,   186,   421,   422,   127,   303,   308,   212,   213,   297,
     341,   383,    75,   218,   129,   204,   219,   215,   309,   359,
     420,   360,   254,   217,   354,   377,   376,   419,   311,   312,
     384,   221,   187,   328,   398,   329
};

/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
   STATE-NUM.  */
#define YYPACT_NINF -293
static const short int yypact[] =
{
     610,  -293,  -293,   266,  -293,  -293,  1426,  1426,  -293,  -293,
    -293,    27,    35,  -293,    52,  -293,  1443,   -54,  -293,   143,
    -293,  -293,  -293,  -293,   218,   -25,  -293,  -293,  -293,  -293,
     384,    -3,    11,    63,    51,   258,  -293,   349,    40,  1426,
    1426,  1426,  1426,    40,    40,  1426,  1426,  1426,  1426,  1426,
      40,    40,  1426,  1426,    28,  1426,  1426,  1426,    36,  1426,
      40,  1426,  -293,  -293,   355,  -293,  -293,  -293,  -293,  -293,
    -293,   114,   119,   576,  -293,  1544,  -293,  -293,    80,  -293,
      57,  -293,  -293,    86,  -293,  -293,   203,  -293,  -293,  -293,
    -293,  -293,   129,  -293,  -293,  -293,   293,    16,    55,  1426,
      16,   394,   122,  -293,   734,  1724,  1724,  1724,   407,  -293,
    -293,   407,   407,   407,   407,   407,  -293,  -293,   407,   407,
     -13,   407,   407,   407,    97,    17,   734,    89,  1544,  1073,
    -293,   144,  -293,  -293,  -293,  -293,  -293,  1426,  1426,  1426,
    1426,  1426,  1426,  1426,  1426,  1426,  1426,  1426,  1426,  1426,
    1426,  1426,  1426,  1426,  1426,  1426,  1426,  1426,  1426,  1426,
    1426,  1426,   815,  1426,  1426,  1426,  1426,  1426,   126,  -293,
    1426,   104,  -293,  -293,    90,  -293,  -293,  1480,  -293,  -293,
     293,   293,    40,   185,   150,   120,  -293,   620,   236,   214,
    -293,   270,   321,   117,  -293,   422,   134,  -293,  -293,  1367,
      -1,   896,  -293,  -293,  1426,    36,  1426,  1426,  -293,  -293,
    -293,   310,  -293,   -49,  -293,   155,  -293,   155,   140,  1426,
    1544,   202,  1584,  1584,  1622,  1622,  1659,  1692,  1724,  1755,
    1785,  1814,  1841,  1841,  1864,  1864,  1864,  1864,  1885,  1885,
    1904,  1904,   498,   498,   498,   498,  -293,   387,   634,   283,
     283,    17,   197,  -293,  1426,  -293,  -293,   645,   135,   -28,
    1426,    23,   122,   186,  -293,   231,  -293,  -293,  -293,   293,
     293,   293,   293,   293,   293,  -293,  -293,  -293,  -293,  -293,
     145,  -293,  1426,  -293,    40,  -293,  -293,  -293,  -293,  -293,
     171,  -293,   955,   479,  -293,   191,  -293,  -293,   209,    17,
     176,   -37,    62,  1426,  1133,  -293,  1073,  1193,  -293,   155,
    -293,   163,  1426,  1584,  1426,  -293,  -293,   212,   496,  -293,
    -293,   149,  1544,   247,  -293,  -293,  -293,  -293,   155,  1426,
    -293,   603,   603,   112,   306,  -293,   236,  -293,   338,  -293,
    -293,  -293,  -293,   896,  1014,  1426,  -293,  -293,  -293,  1544,
    -293,  -293,   239,  -293,   402,  -293,   198,  1544,  1544,  1252,
    1313,  -293,  -293,  1426,   135,  -293,  -293,  1463,  -293,  1544,
    -293,  1426,  -293,  -293,  -293,    73,  1426,  1426,  -293,  -293,
    -293,  -293,  -293,  1426,  1426,   257,   246,  1544,  -293,   344,
     178,  -293,  -293,  -293,  -293,  -293,    38,   384,   402,  -293,
    -293,   407,   407,  1544,  1544,  -293,  -293,  1426,   208,   450,
     280,   280,  1426,  1426,   429,  -293,    75,  1426,   293,  1426,
    1313,  -293,   279,   276,   297,  -293,   221,  -293,  -293,   289,
    -293,  -293,  -293,  -293,    38,  -293,    60,  -293,  1544,   620,
     407,   284,  1426,   333,  -293,   252,  1426,  -293,   325,   478,
    -293,  -293,   221,  -293,   369,  -293,  -293,   375,  -293,  -293,
    -293,  -293,   155,  1426,  -293,   279
};

/* YYPGOTO[NTERM-NUM].  */
static const short int yypgoto[] =
{
    -293,  -293,  -293,   123,   -12,  -293,  -293,    10,  -293,   125,
    -293,    48,    50,   105,   245,  -179,     0,   -79,    29,   130,
      85,  -293,  -185,    65,   324,  -293,  -293,    18,  -293,  -293,
    -293,  -293,  -293,  -293,  -293,  -293,    -6,  -293,  -293,  -293,
    -293,  -293,  -293,  -293,  -293,  -293,  -293,  -293,  -293,  -293,
       9,  -293,  -293,    53,  -293,    39,  -293,   113,     5,  -293,
       6,  -293,    58,  -293,  -293,  -293,  -293,  -293,  -293,    96,
    -293,   238,  -289,   -23,  -198,  -293,  -207,   207,  -293,  -292,
      -5,   128,   329,  -293,  -293,  -293,  -293,  -293,  -293,  -293,
    -293,  -293,  -293,  -293,  -293,  -293,  -293,  -293,  -293,  -293,
    -293,  -293,  -154,  -293,  -293,  -293
};

/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
   positive, shift that token.  If negative, reduce the rule which
   number is the opposite.  If zero, do what YYDEFACT says.
   If YYTABLE_NINF, syntax error.  */
#define YYTABLE_NINF -274
static const short int yytable[] =
{
      20,    74,    76,    20,    83,    24,    25,   284,   301,   302,
     310,    77,    79,    35,   348,   352,    20,     1,   205,    77,
     290,    24,    25,    84,    89,   203,   264,   265,     1,     1,
     305,   -47,    90,    91,   306,    77,     1,     1,   104,  -114,
      78,     1,   346,    20,    20,   101,   210,   208,    85,   277,
      20,    20,    81,   320,    77,   279,     1,    31,    77,   -47,
     126,     1,   168,   169,   103,   206,     2,   385,   386,   101,
     -27,   131,   -47,    77,   321,    97,     1,     2,     2,   291,
      32,    33,    34,   120,   170,     2,     2,   124,  -114,    98,
       2,     1,   179,   -63,   194,   -63,    20,    20,   190,   -63,
      20,    20,   353,   337,    79,     2,   -47,   -47,   343,    99,
       2,   200,  -114,   -45,   -47,     1,   331,   332,   333,   334,
     335,   368,   273,   274,   214,     2,    79,     1,   441,   100,
       1,   132,   -52,   178,   -52,   171,     1,   -47,   -52,   -47,
       2,   347,   -47,   -47,     1,   210,     1,   375,   130,   435,
       1,     1,   400,   451,   -47,   -47,   210,   -47,   -47,   -47,
     -47,   -47,    77,   172,     2,   255,   133,   -74,   253,   201,
     209,   -74,   210,   -74,    20,   207,     2,    20,   216,     2,
      20,    20,   266,   256,    77,     2,    31,   261,    77,   267,
     -47,   246,   399,     2,   194,     2,   298,   285,     1,     2,
       2,   134,   307,   269,   252,    77,   314,    90,    91,    32,
      33,    34,   -47,   268,   287,   173,   -47,   275,   -47,     1,
     325,  -268,   -62,  -268,   -62,   -47,   -73,   -47,   -62,   434,
     -73,   -47,   -73,   -47,   300,  -123,  -123,     1,   270,   271,
     272,   273,   274,   315,   355,    19,   356,     2,    36,   317,
     174,   339,   316,   454,   345,   464,   -47,    20,    77,     1,
     344,    19,    24,    25,   439,   423,   424,     1,     2,    20,
      20,    20,    20,    20,    20,    87,    88,   194,   -39,  -273,
      20,  -273,   101,   -27,   190,   175,     2,   319,   109,   110,
     336,   277,   361,   278,     1,   116,   117,   279,  -119,   350,
    -119,   214,     2,   365,   101,   -27,    83,    31,     2,   455,
     456,   -43,   327,   -47,   304,   -47,     2,   274,    20,   -47,
     378,    20,   -43,    24,    25,   406,   167,   180,   168,   169,
      32,    33,    34,  -124,  -124,   -47,    77,   405,   298,   374,
     181,   182,    36,     2,   -43,    36,    36,   -53,   407,   -53,
     -44,     5,   281,   -53,  -125,  -125,   -43,   -43,   426,   459,
     -43,   -44,   442,   450,    77,   275,   194,   -43,   105,   106,
     107,   108,   446,   -44,   111,   112,   113,   114,   115,   461,
     318,   118,   119,   -44,   121,   122,   123,   324,   125,   -43,
     128,   372,   -43,   388,   373,     1,   -44,   340,   277,   -44,
     283,   370,   -43,   379,   279,   -43,   380,   431,   432,    77,
     452,   381,   453,   382,   338,   -54,    20,   -54,    20,   258,
     281,   -54,    36,   371,   195,   182,   182,   164,   165,   166,
     167,   -44,   168,   169,   437,    31,   448,   -43,   425,   457,
     465,   431,   196,   447,     2,    77,   163,   164,   165,   166,
     167,     1,   168,   169,   -47,    93,    94,    95,    32,    33,
      34,   197,   198,   397,   428,   449,   220,   222,   223,   224,
     225,   226,   227,   228,   229,   230,   231,   232,   233,   234,
     235,   236,   237,   238,   239,   240,   241,   242,   243,   244,
     245,   460,   247,   248,   249,   250,   251,     1,   -47,   277,
       2,   286,    19,   408,   458,   279,   277,   330,   433,   -47,
     -47,   -47,   279,   351,   182,   182,   182,   182,   182,   182,
       0,   -47,   -47,   -47,   -47,    36,   418,   -47,   -47,   161,
     162,     0,     0,   299,     0,   128,   128,   163,   164,   165,
     166,   167,     0,   168,   169,     0,     2,     0,   313,     0,
       0,     3,     0,     4,     5,  -110,   277,  -110,     6,     7,
     342,  -110,   279,    19,     0,     0,   364,     8,     9,    10,
       0,    11,    12,    82,     0,   362,     0,     1,     0,   -47,
     -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,     0,   322,
       0,   -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,
     -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,     0,
      -3,     1,   272,   273,   274,   -47,   -47,   -47,   -47,   -47,
       0,   -47,   -47,     0,   -47,     0,     2,   270,   271,   272,
     273,   274,   349,    87,    88,   -47,   -47,   -47,     0,     0,
       0,   357,     0,   358,     0,   -47,     1,   -47,   -47,   -47,
     -47,     0,     0,   -47,   -47,   -47,   -47,   -47,   369,   -47,
       2,   436,     0,   182,     0,     3,     0,     4,     5,     0,
       0,     0,     6,     7,   128,   165,   166,   167,     0,   168,
     169,     8,     9,    10,     0,    11,    12,    13,     0,     0,
       0,     0,   387,     0,     0,     2,     0,     0,     0,     0,
       3,     0,     4,     5,     0,   401,   402,     6,     7,     0,
       0,     0,   403,   404,     0,     0,     8,     9,    10,     0,
      11,    12,    13,     0,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     0,     0,     1,   349,   -45,   -45,   -45,
     -45,   -45,   -45,   -45,   -45,   -45,   438,     0,   440,   -45,
     -45,   -45,   -45,   -45,   -45,   -45,   -45,   -45,   -45,   -45,
     -45,   -45,   -45,   -45,   -45,   -45,   -45,     0,     0,     0,
       0,   349,     0,   -45,   -45,   -45,   -45,   -45,     0,   -45,
     -45,     0,   -45,     0,     2,     0,     0,     0,     0,     0,
       0,     0,   349,   -45,   -45,   -45,     0,     0,     0,     0,
       0,     0,     0,   -45,     0,   -45,   -45,   -45,   -45,     0,
       0,   -45,   -45,   -45,   -45,   -45,     1,   -45,   -47,   -47,
     -47,   -47,   -47,   -47,   -47,   -47,   -47,     0,     0,     0,
     -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,
     -47,   -47,   -47,   -47,   -47,   -47,   -47,   -47,     0,     0,
       0,     0,     0,     0,   -47,   -47,   -47,   -47,   -47,     0,
     -47,   -47,     0,   -47,     0,     2,     0,     0,     0,     0,
       0,     0,     0,     0,   -47,   -47,   -47,     0,     0,     0,
       0,     0,     0,     0,   -47,     0,   -47,   -47,   -47,   -47,
       0,     0,   -47,   -47,   -47,   -47,   -47,    37,   -47,     0,
      38,     0,     0,     0,     0,     0,     0,     0,    39,    40,
      41,    42,     0,     0,     0,     0,    43,    44,     0,     0,
       0,     0,    45,    46,    47,    48,    49,    50,    51,    52,
      53,    54,    55,    56,    57,     0,    58,     0,     0,     0,
      59,    60,     0,    61,    62,    63,    64,    65,    66,    67,
      68,     0,     0,     4,     0,     0,    37,     0,     0,    38,
       0,     0,     0,     0,     0,   292,    69,    39,    40,    41,
      42,     0,     0,  -169,    70,    43,    44,  -169,     0,  -169,
       0,    45,    46,    47,    48,    49,    50,    51,    52,    53,
      54,    55,    56,    57,     0,    58,     0,     0,     0,    59,
      60,     0,    61,    62,    63,    64,    65,    66,    67,    68,
       0,     0,     4,     0,     0,    37,     0,     0,    38,     0,
       0,     0,     0,     0,     0,    69,    39,    40,    41,    42,
       0,     0,  -169,    70,    43,    44,  -169,     0,  -169,     0,
      45,    46,    47,    48,    49,    50,    51,    52,    53,    54,
      55,    56,    57,     0,    58,     0,     0,     0,    59,    60,
       0,    61,    62,    63,    64,    65,    66,    67,    68,     0,
       0,     4,     0,     0,    37,     0,     0,    38,     0,     0,
       0,     0,     0,     0,    69,    39,    40,    41,    42,     0,
       0,   -38,    70,    43,    44,   -38,     0,   -38,     0,    45,
      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
      56,    57,     0,    58,     0,     0,     0,    59,    60,     0,
      61,    62,    63,   211,    65,    66,    67,    68,     0,     0,
       4,     0,     0,     0,    37,     0,     0,    38,     0,     0,
       0,     0,     0,    69,     0,    39,    40,    41,    42,     0,
       0,    70,  -163,    43,    44,     0,  -163,     0,     0,    45,
      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
      56,    57,     0,    58,     0,     0,     0,    59,    60,     0,
      61,    62,    63,    64,    65,    66,    67,    68,     0,     0,
       4,     0,     0,     0,    37,     0,     0,    38,     0,     0,
       0,     0,     0,    69,     0,    39,    40,    41,    42,     0,
       0,    70,  -165,    43,    44,     0,  -165,     0,     0,    45,
      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
      56,    57,     0,    58,     0,     0,     0,    59,    60,     0,
      61,    62,    63,    64,    65,    66,    67,    68,     0,     0,
       4,     0,     0,    37,     0,     0,    38,     0,     0,     0,
       0,     0,     0,    69,    39,    40,    41,    42,     0,     0,
       0,    70,    43,    44,  -169,     0,     0,     0,    45,    46,
      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
      57,     0,    58,     0,     0,     0,    59,    60,     0,    61,
      62,    63,    64,    65,    66,    67,    68,     0,     0,     4,
       0,     0,     0,     0,    37,     0,     0,    38,     0,     0,
       0,     0,    69,     0,     0,    39,    40,    41,    42,     0,
      70,     0,  -169,    43,    44,     0,     0,     0,     0,    45,
      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
      56,    57,     0,    58,     0,     0,     0,    59,    60,     0,
      61,    62,    63,    64,    65,    66,    67,    68,    37,     0,
       4,    38,     0,     0,     0,     0,     0,     0,     0,    39,
      40,    41,    42,    69,     0,     0,     0,    43,    44,     0,
       0,    70,  -169,    45,    46,    47,    48,    49,    50,    51,
      52,    53,    54,    55,    56,    57,     0,    58,     0,     0,
       0,    59,    60,     0,    61,    62,    63,    64,    65,    66,
      67,    68,     0,     0,     4,     0,     0,    37,     0,     0,
      38,     0,     0,     0,   288,   289,     0,    69,    39,    40,
      41,    42,     0,    -4,     1,    70,    43,    44,     0,     0,
       0,     0,    45,    46,    47,    48,    49,    50,    51,    52,
      53,    54,    55,    56,    57,     0,    58,   390,     0,     0,
      59,    60,     0,    61,    62,    63,    64,    65,    66,    67,
      68,     1,     0,     4,     0,     0,     0,     0,     0,     0,
       0,     0,     0,     2,     0,     0,    69,     0,     3,     0,
       4,     5,     0,     0,    70,     6,     7,     0,     0,     0,
       0,   391,     0,     0,     8,     9,    10,     0,    11,    12,
      82,    31,   392,   393,   394,     0,     0,   -76,     0,     0,
       2,     0,     0,     0,     8,     9,    10,   395,     0,     0,
       0,   396,     0,     0,    32,    33,    34,   137,     0,   138,
     139,   140,   141,   142,   143,   144,     0,     0,     0,   145,
     146,   147,   148,   149,   150,   151,   152,   153,   154,   155,
     156,   157,   158,   159,   160,   161,   162,     0,     0,     0,
       0,     0,     0,   163,   164,   165,   166,   167,     0,   168,
     169,   140,   141,   142,   143,   144,     0,     0,     0,   145,
     146,   147,   148,   149,   150,   151,   152,   153,   154,   155,
     156,   157,   158,   159,   160,   161,   162,     0,     0,     0,
       0,     0,     0,   163,   164,   165,   166,   167,     0,   168,
     169,   142,   143,   144,     0,     0,     0,   145,   146,   147,
     148,   149,   150,   151,   152,   153,   154,   155,   156,   157,
     158,   159,   160,   161,   162,     0,     0,     0,     0,     0,
       0,   163,   164,   165,   166,   167,     0,   168,   169,   143,
     144,     0,     0,     0,   145,   146,   147,   148,   149,   150,
     151,   152,   153,   154,   155,   156,   157,   158,   159,   160,
     161,   162,     0,     0,     0,     0,     0,     0,   163,   164,
     165,   166,   167,   144,   168,   169,     0,   145,   146,   147,
     148,   149,   150,   151,   152,   153,   154,   155,   156,   157,
     158,   159,   160,   161,   162,     0,     0,     0,     0,     0,
       0,   163,   164,   165,   166,   167,     0,   168,   169,   145,
     146,   147,   148,   149,   150,   151,   152,   153,   154,   155,
     156,   157,   158,   159,   160,   161,   162,     0,     0,     0,
       0,     0,     0,   163,   164,   165,   166,   167,     0,   168,
     169,   146,   147,   148,   149,   150,   151,   152,   153,   154,
     155,   156,   157,   158,   159,   160,   161,   162,     0,     0,
       0,     0,     0,     0,   163,   164,   165,   166,   167,     0,
     168,   169,   147,   148,   149,   150,   151,   152,   153,   154,
     155,   156,   157,   158,   159,   160,   161,   162,     0,     0,
       0,     0,     0,     0,   163,   164,   165,   166,   167,     0,
     168,   169,   148,   149,   150,   151,   152,   153,   154,   155,
     156,   157,   158,   159,   160,   161,   162,     0,     0,     0,
       0,     0,     0,   163,   164,   165,   166,   167,     0,   168,
     169,   150,   151,   152,   153,   154,   155,   156,   157,   158,
     159,   160,   161,   162,     0,     0,     0,     0,     0,     0,
     163,   164,   165,   166,   167,     0,   168,   169,   154,   155,
     156,   157,   158,   159,   160,   161,   162,     0,     0,     0,
       0,     0,     0,   163,   164,   165,   166,   167,     0,   168,
     169,   156,   157,   158,   159,   160,   161,   162,     0,     0,
       0,     0,     0,     0,   163,   164,   165,   166,   167,     0,
     168,   169,   158,   159,   160,   161,   162,     0,     0,     0,
       0,     0,     0,   163,   164,   165,   166,   167,     0,   168,
     169
};

static const short int yycheck[] =
{
       0,     6,     7,     3,    16,     0,     0,   192,   206,   207,
     217,    11,    12,     3,   303,   307,    16,     1,    31,    19,
     199,    16,    16,    77,    24,   104,   180,   181,     1,     1,
      79,     4,    57,    58,    83,    35,     1,     1,    38,     1,
      11,     1,    79,    43,    44,    46,    83,   126,    19,    77,
      50,    51,     0,    81,    54,    83,     1,    41,    58,    31,
      60,     1,    45,    46,    35,    78,    50,   359,   360,    46,
      47,    71,    12,    73,   259,    78,     1,    50,    50,    80,
      64,    65,    66,    54,     4,    50,    50,    58,    50,    78,
      50,     1,    92,    77,    99,    79,    96,    97,    98,    83,
     100,   101,   309,   282,   104,    50,    78,    47,   293,    46,
      50,   101,    74,    78,    78,     1,   270,   271,   272,   273,
     274,   328,    10,    11,   129,    50,   126,     1,   420,    78,
       1,    12,    77,     4,    79,    78,     1,    77,    83,    79,
      50,    79,    82,    83,     1,    83,     1,   345,    34,    74,
       1,     1,    79,   442,     4,    12,    83,     7,     8,     9,
      10,    11,   162,    77,    50,   170,    47,    77,   168,    47,
      81,    81,    83,    83,   174,    78,    50,   177,    34,    50,
     180,   181,   182,    79,   184,    50,    41,   177,   188,     4,
      47,   162,   371,    50,   199,    50,   201,    80,     1,    50,
      50,    82,    47,    83,    78,   205,     4,    57,    58,    64,
      65,    66,    77,   184,    80,    12,    81,   188,    83,     1,
      34,    81,    77,    83,    79,    82,    77,    77,    83,   414,
      81,    81,    83,    83,   205,    57,    58,     1,     7,     8,
       9,    10,    11,    46,    81,     0,    83,    50,     3,   254,
      47,    80,   252,     1,    78,   462,     4,   257,   258,     1,
      69,    16,   257,   257,   418,    57,    58,     1,    50,   269,
     270,   271,   272,   273,   274,    57,    58,   282,    69,    81,
     280,    83,    46,    47,   284,    82,    50,   258,    43,    44,
     280,    77,    80,    79,     1,    50,    51,    83,    77,   304,
      79,   306,    50,    56,    46,    47,   318,    41,    50,    57,
      58,     1,    81,    77,     4,    79,    50,    11,   318,    83,
      81,   321,    12,   318,   318,    79,    43,    34,    45,    46,
      64,    65,    66,    57,    58,    77,   336,    80,   343,   344,
      47,    96,    97,    50,    34,   100,   101,    77,     4,    79,
       1,    58,    82,    83,    57,    58,     1,    47,    78,    34,
      50,    12,    83,    79,   364,   336,   371,    12,    39,    40,
      41,    42,    83,     4,    45,    46,    47,    48,    49,     4,
     257,    52,    53,    34,    55,    56,    57,   262,    59,    34,
      61,   343,    82,   364,   344,     1,    47,   292,    77,    50,
      79,   336,    47,     1,    83,    50,     4,   412,   413,   409,
      77,     9,    79,    11,   284,    77,   416,    79,   418,   174,
      82,    83,   177,   338,   100,   180,   181,    40,    41,    42,
      43,    82,    45,    46,   416,    41,   436,    82,   409,   445,
     463,   446,    48,   434,    50,   445,    39,    40,    41,    42,
      43,     1,    45,    46,     4,    71,    72,    73,    64,    65,
      66,    67,    68,   367,   411,   436,   137,   138,   139,   140,
     141,   142,   143,   144,   145,   146,   147,   148,   149,   150,
     151,   152,   153,   154,   155,   156,   157,   158,   159,   160,
     161,   452,   163,   164,   165,   166,   167,     1,    48,    77,
      50,    79,   257,   390,   446,    83,    77,   269,    79,    59,
      60,    61,    83,   306,   269,   270,   271,   272,   273,   274,
      -1,    71,    72,    73,    74,   280,   398,    77,    78,    31,
      32,    -1,    -1,   204,    -1,   206,   207,    39,    40,    41,
      42,    43,    -1,    45,    46,    -1,    50,    -1,   219,    -1,
      -1,    55,    -1,    57,    58,    77,    77,    79,    62,    63,
      81,    83,    83,   318,    -1,    -1,   321,    71,    72,    73,
      -1,    75,    76,    77,    -1,    79,    -1,     1,    -1,     3,
       4,     5,     6,     7,     8,     9,    10,    11,    -1,   260,
      -1,    15,    16,    17,    18,    19,    20,    21,    22,    23,
      24,    25,    26,    27,    28,    29,    30,    31,    32,    -1,
       0,     1,     9,    10,    11,    39,    40,    41,    42,    43,
      -1,    45,    46,    -1,    48,    -1,    50,     7,     8,     9,
      10,    11,   303,    57,    58,    59,    60,    61,    -1,    -1,
      -1,   312,    -1,   314,    -1,    69,     1,    71,    72,    73,
      74,    -1,    -1,    77,    78,    79,    80,    81,   329,    83,
      50,   416,    -1,   418,    -1,    55,    -1,    57,    58,    -1,
      -1,    -1,    62,    63,   345,    41,    42,    43,    -1,    45,
      46,    71,    72,    73,    -1,    75,    76,    77,    -1,    -1,
      -1,    -1,   363,    -1,    -1,    50,    -1,    -1,    -1,    -1,
      55,    -1,    57,    58,    -1,   376,   377,    62,    63,    -1,
      -1,    -1,   383,   384,    -1,    -1,    71,    72,    73,    -1,
      75,    76,    77,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    -1,     1,   407,     3,     4,     5,
       6,     7,     8,     9,    10,    11,   417,    -1,   419,    15,
      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,   442,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46,    -1,    48,    -1,    50,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,   463,    59,    60,    61,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    69,    -1,    71,    72,    73,    74,    -1,
      -1,    77,    78,    79,    80,    81,     1,    83,     3,     4,
       5,     6,     7,     8,     9,    10,    11,    -1,    -1,    -1,
      15,    16,    17,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
      -1,    -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,
      45,    46,    -1,    48,    -1,    50,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    59,    60,    61,    -1,    -1,    -1,
      -1,    -1,    -1,    -1,    69,    -1,    71,    72,    73,    74,
      -1,    -1,    77,    78,    79,    80,    81,     1,    83,    -1,
       4,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    12,    13,
      14,    15,    -1,    -1,    -1,    -1,    20,    21,    -1,    -1,
      -1,    -1,    26,    27,    28,    29,    30,    31,    32,    33,
      34,    35,    36,    37,    38,    -1,    40,    -1,    -1,    -1,
      44,    45,    -1,    47,    48,    49,    50,    51,    52,    53,
      54,    -1,    -1,    57,    -1,    -1,     1,    -1,    -1,     4,
      -1,    -1,    -1,    -1,    -1,    69,    70,    12,    13,    14,
      15,    -1,    -1,    77,    78,    20,    21,    81,    -1,    83,
      -1,    26,    27,    28,    29,    30,    31,    32,    33,    34,
      35,    36,    37,    38,    -1,    40,    -1,    -1,    -1,    44,
      45,    -1,    47,    48,    49,    50,    51,    52,    53,    54,
      -1,    -1,    57,    -1,    -1,     1,    -1,    -1,     4,    -1,
      -1,    -1,    -1,    -1,    -1,    70,    12,    13,    14,    15,
      -1,    -1,    77,    78,    20,    21,    81,    -1,    83,    -1,
      26,    27,    28,    29,    30,    31,    32,    33,    34,    35,
      36,    37,    38,    -1,    40,    -1,    -1,    -1,    44,    45,
      -1,    47,    48,    49,    50,    51,    52,    53,    54,    -1,
      -1,    57,    -1,    -1,     1,    -1,    -1,     4,    -1,    -1,
      -1,    -1,    -1,    -1,    70,    12,    13,    14,    15,    -1,
      -1,    77,    78,    20,    21,    81,    -1,    83,    -1,    26,
      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
      37,    38,    -1,    40,    -1,    -1,    -1,    44,    45,    -1,
      47,    48,    49,    50,    51,    52,    53,    54,    -1,    -1,
      57,    -1,    -1,    -1,     1,    -1,    -1,     4,    -1,    -1,
      -1,    -1,    -1,    70,    -1,    12,    13,    14,    15,    -1,
      -1,    78,    79,    20,    21,    -1,    83,    -1,    -1,    26,
      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
      37,    38,    -1,    40,    -1,    -1,    -1,    44,    45,    -1,
      47,    48,    49,    50,    51,    52,    53,    54,    -1,    -1,
      57,    -1,    -1,    -1,     1,    -1,    -1,     4,    -1,    -1,
      -1,    -1,    -1,    70,    -1,    12,    13,    14,    15,    -1,
      -1,    78,    79,    20,    21,    -1,    83,    -1,    -1,    26,
      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
      37,    38,    -1,    40,    -1,    -1,    -1,    44,    45,    -1,
      47,    48,    49,    50,    51,    52,    53,    54,    -1,    -1,
      57,    -1,    -1,     1,    -1,    -1,     4,    -1,    -1,    -1,
      -1,    -1,    -1,    70,    12,    13,    14,    15,    -1,    -1,
      -1,    78,    20,    21,    81,    -1,    -1,    -1,    26,    27,
      28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
      38,    -1,    40,    -1,    -1,    -1,    44,    45,    -1,    47,
      48,    49,    50,    51,    52,    53,    54,    -1,    -1,    57,
      -1,    -1,    -1,    -1,     1,    -1,    -1,     4,    -1,    -1,
      -1,    -1,    70,    -1,    -1,    12,    13,    14,    15,    -1,
      78,    -1,    80,    20,    21,    -1,    -1,    -1,    -1,    26,
      27,    28,    29,    30,    31,    32,    33,    34,    35,    36,
      37,    38,    -1,    40,    -1,    -1,    -1,    44,    45,    -1,
      47,    48,    49,    50,    51,    52,    53,    54,     1,    -1,
      57,     4,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    12,
      13,    14,    15,    70,    -1,    -1,    -1,    20,    21,    -1,
      -1,    78,    79,    26,    27,    28,    29,    30,    31,    32,
      33,    34,    35,    36,    37,    38,    -1,    40,    -1,    -1,
      -1,    44,    45,    -1,    47,    48,    49,    50,    51,    52,
      53,    54,    -1,    -1,    57,    -1,    -1,     1,    -1,    -1,
       4,    -1,    -1,    -1,    67,    68,    -1,    70,    12,    13,
      14,    15,    -1,     0,     1,    78,    20,    21,    -1,    -1,
      -1,    -1,    26,    27,    28,    29,    30,    31,    32,    33,
      34,    35,    36,    37,    38,    -1,    40,     4,    -1,    -1,
      44,    45,    -1,    47,    48,    49,    50,    51,    52,    53,
      54,     1,    -1,    57,    -1,    -1,    -1,    -1,    -1,    -1,
      -1,    -1,    -1,    50,    -1,    -1,    70,    -1,    55,    -1,
      57,    58,    -1,    -1,    78,    62,    63,    -1,    -1,    -1,
      -1,    48,    -1,    -1,    71,    72,    73,    -1,    75,    76,
      77,    41,    59,    60,    61,    -1,    -1,    47,    -1,    -1,
      50,    -1,    -1,    -1,    71,    72,    73,    74,    -1,    -1,
      -1,    78,    -1,    -1,    64,    65,    66,     3,    -1,     5,
       6,     7,     8,     9,    10,    11,    -1,    -1,    -1,    15,
      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46,     7,     8,     9,    10,    11,    -1,    -1,    -1,    15,
      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46,     9,    10,    11,    -1,    -1,    -1,    15,    16,    17,
      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
      -1,    39,    40,    41,    42,    43,    -1,    45,    46,    10,
      11,    -1,    -1,    -1,    15,    16,    17,    18,    19,    20,
      21,    22,    23,    24,    25,    26,    27,    28,    29,    30,
      31,    32,    -1,    -1,    -1,    -1,    -1,    -1,    39,    40,
      41,    42,    43,    11,    45,    46,    -1,    15,    16,    17,
      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
      28,    29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,
      -1,    39,    40,    41,    42,    43,    -1,    45,    46,    15,
      16,    17,    18,    19,    20,    21,    22,    23,    24,    25,
      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46,    16,    17,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
      -1,    -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,
      45,    46,    17,    18,    19,    20,    21,    22,    23,    24,
      25,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
      -1,    -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,
      45,    46,    18,    19,    20,    21,    22,    23,    24,    25,
      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46,    20,    21,    22,    23,    24,    25,    26,    27,    28,
      29,    30,    31,    32,    -1,    -1,    -1,    -1,    -1,    -1,
      39,    40,    41,    42,    43,    -1,    45,    46,    24,    25,
      26,    27,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46,    26,    27,    28,    29,    30,    31,    32,    -1,    -1,
      -1,    -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,
      45,    46,    28,    29,    30,    31,    32,    -1,    -1,    -1,
      -1,    -1,    -1,    39,    40,    41,    42,    43,    -1,    45,
      46
};

/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
   symbol of state STATE-NUM.  */
static const unsigned char yystos[] =
{
       0,     1,    50,    55,    57,    58,    62,    63,    71,    72,
      73,    75,    76,    77,    85,    86,    87,    88,    89,    98,
     100,   111,   118,   124,   142,   144,   147,   148,   149,   151,
     153,    41,    64,    65,    66,    91,    98,     1,     4,    12,
      13,    14,    15,    20,    21,    26,    27,    28,    29,    30,
      31,    32,    33,    34,    35,    36,    37,    38,    40,    44,
      45,    47,    48,    49,    50,    51,    52,    53,    54,    70,
      78,    98,   100,   142,   164,   166,   164,   100,   102,   100,
     101,     0,    77,    88,    77,   102,   110,    57,    58,   100,
      57,    58,   122,    71,    72,    73,   152,    78,    78,    46,
      78,    46,    92,   102,   100,   166,   166,   166,   166,    98,
      98,   166,   166,   166,   166,   166,    98,    98,   166,   166,
     102,   166,   166,   166,   102,   166,   100,   158,   166,   168,
      34,   100,    12,    47,    82,   102,   120,     3,     5,     6,
       7,     8,     9,    10,    11,    15,    16,    17,    18,    19,
      20,    21,    22,    23,    24,    25,    26,    27,    28,    29,
      30,    31,    32,    39,    40,    41,    42,    43,    45,    46,
       4,    78,    77,    12,    47,    82,   109,   115,     4,   100,
      34,    47,    98,   126,   144,   154,   155,   186,    91,   108,
     100,   103,   105,    99,   164,   108,    48,    67,    68,    90,
      91,    47,    93,   101,   169,    31,    78,    78,   101,    81,
      83,    50,   161,   162,   164,   171,    34,   177,   167,   170,
     166,   185,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   166,   166,   166,   166,
     166,   166,   166,   166,   166,   166,   102,   166,   166,   166,
     166,   166,    78,   100,   176,   164,    79,   150,    98,   114,
     112,    91,   116,   123,   186,   186,   100,     4,   102,    83,
       7,     8,     9,    10,    11,   102,   107,    77,    79,    83,
     106,    82,   104,    79,   106,    80,    79,    80,    67,    68,
      99,    80,    69,    94,    95,    96,    97,   163,   164,   166,
     102,   158,   158,   159,     4,    79,    83,    47,   160,   172,
     160,   182,   183,   166,     4,    46,   100,   164,    87,   102,
      81,   106,   166,   117,    93,    34,   125,    81,   187,   189,
     155,   186,   186,   186,   186,   186,    91,    99,   103,    80,
      97,   164,    81,   106,    69,    78,    79,    79,   156,   166,
     164,   161,   163,   160,   178,    81,    83,   166,   166,   173,
     175,    80,    79,   113,    98,    56,   119,   127,   160,   166,
     107,   104,    95,    96,   164,   158,   180,   179,    81,     1,
       4,     9,    11,   165,   184,   163,   163,   166,   102,   121,
       4,    48,    59,    60,    61,    74,    78,   153,   188,    99,
      79,   166,   166,   166,   166,    80,    79,     4,   141,   143,
     128,   129,   130,   132,   133,   134,   136,   131,   165,   181,
     174,   156,   157,    57,    58,   102,    78,   137,   137,   145,
     146,   164,   164,    79,   106,    74,    98,   111,   166,   186,
     166,   163,    83,   138,   139,   141,    83,   134,   100,   102,
      79,   156,    77,    79,     1,    57,    58,   120,   146,    34,
     139,     4,   135,   140,   160,   157
};

#if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
# define YYSIZE_T __SIZE_TYPE__
#endif
#if ! defined (YYSIZE_T) && defined (size_t)
# define YYSIZE_T size_t
#endif
#if ! defined (YYSIZE_T)
# if defined (__STDC__) || defined (__cplusplus)
#  include <stddef.h> /* INFRINGES ON USER NAME SPACE */
#  define YYSIZE_T size_t
# endif
#endif
#if ! defined (YYSIZE_T)
# define YYSIZE_T unsigned int
#endif

#define yyerrok		(yyerrstatus = 0)
#define yyclearin	(yychar = YYEMPTY)
#define YYEMPTY		(-2)
#define YYEOF		0

#define YYACCEPT	goto yyacceptlab
#define YYABORT		goto yyabortlab
#define YYERROR		goto yyerrorlab


/* Like YYERROR except do call yyerror.  This remains here temporarily
   to ease the transition to the new meaning of YYERROR, for GCC.
   Once GCC version 2 has supplanted version 1, this can go.  */

#define YYFAIL		goto yyerrlab

#define YYRECOVERING()  (!!yyerrstatus)

#define YYBACKUP(Token, Value)					\
do								\
  if (yychar == YYEMPTY && yylen == 1)				\
    {								\
      yychar = (Token);						\
      yylval = (Value);						\
      yytoken = YYTRANSLATE (yychar);				\
      YYPOPSTACK;						\
      goto yybackup;						\
    }								\
  else								\
    { 								\
      yyerror ("syntax error: cannot back up");\
      YYERROR;							\
    }								\
while (0)

#define YYTERROR	1
#define YYERRCODE	256

/* YYLLOC_DEFAULT -- Compute the default location (before the actions
   are run).  */

#ifndef YYLLOC_DEFAULT
# define YYLLOC_DEFAULT(Current, Rhs, N)		\
   ((Current).first_line   = (Rhs)[1].first_line,	\
    (Current).first_column = (Rhs)[1].first_column,	\
    (Current).last_line    = (Rhs)[N].last_line,	\
    (Current).last_column  = (Rhs)[N].last_column)
#endif

/* YYLEX -- calling `yylex' with the right arguments.  */

#ifdef YYLEX_PARAM
# define YYLEX yylex (YYLEX_PARAM)
#else
# define YYLEX yylex ()
#endif

/* Enable debugging if requested.  */
#if YYDEBUG

# ifndef YYFPRINTF
#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
#  define YYFPRINTF fprintf
# endif

# define YYDPRINTF(Args)			\
do {						\
  if (yydebug)					\
    YYFPRINTF Args;				\
} while (0)

# define YYDSYMPRINT(Args)			\
do {						\
  if (yydebug)					\
    yysymprint Args;				\
} while (0)

# define YYDSYMPRINTF(Title, Token, Value, Location)		\
do {								\
  if (yydebug)							\
    {								\
      YYFPRINTF (stderr, "%s ", Title);				\
      yysymprint (stderr, 					\
                  Token, Value);	\
      YYFPRINTF (stderr, "\n");					\
    }								\
} while (0)

/*------------------------------------------------------------------.
| yy_stack_print -- Print the state stack from its BOTTOM up to its |
| TOP (included).                                                   |
`------------------------------------------------------------------*/

#if defined (__STDC__) || defined (__cplusplus)
static void
yy_stack_print (short int *bottom, short int *top)
#else
static void
yy_stack_print (bottom, top)
    short int *bottom;
    short int *top;
#endif
{
  YYFPRINTF (stderr, "Stack now");
  for (/* Nothing. */; bottom <= top; ++bottom)
    YYFPRINTF (stderr, " %d", *bottom);
  YYFPRINTF (stderr, "\n");
}

# define YY_STACK_PRINT(Bottom, Top)				\
do {								\
  if (yydebug)							\
    yy_stack_print ((Bottom), (Top));				\
} while (0)


/*------------------------------------------------.
| Report that the YYRULE is going to be reduced.  |
`------------------------------------------------*/

#if defined (__STDC__) || defined (__cplusplus)
static void
yy_reduce_print (int yyrule)
#else
static void
yy_reduce_print (yyrule)
    int yyrule;
#endif
{
  int yyi;
  unsigned int yylno = yyrline[yyrule];
  YYFPRINTF (stderr, "Reducing stack by rule %d (line %u), ",
             yyrule - 1, yylno);
  /* Print the symbols being reduced, and their result.  */
  for (yyi = yyprhs[yyrule]; 0 <= yyrhs[yyi]; yyi++)
    YYFPRINTF (stderr, "%s ", yytname [yyrhs[yyi]]);
  YYFPRINTF (stderr, "-> %s\n", yytname [yyr1[yyrule]]);
}

# define YY_REDUCE_PRINT(Rule)		\
do {					\
  if (yydebug)				\
    yy_reduce_print (Rule);		\
} while (0)

/* Nonzero means print parse trace.  It is left uninitialized so that
   multiple parsers can coexist.  */
int yydebug;
#else /* !YYDEBUG */
# define YYDPRINTF(Args)
# define YYDSYMPRINT(Args)
# define YYDSYMPRINTF(Title, Token, Value, Location)
# define YY_STACK_PRINT(Bottom, Top)
# define YY_REDUCE_PRINT(Rule)
#endif /* !YYDEBUG */


/* YYINITDEPTH -- initial size of the parser's stacks.  */
#ifndef	YYINITDEPTH
# define YYINITDEPTH 200
#endif

/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
   if the built-in stack extension method is used).

   Do not make this value too large; the results are undefined if
   SIZE_MAX < YYSTACK_BYTES (YYMAXDEPTH)
   evaluated with infinite-precision integer arithmetic.  */

#if defined (YYMAXDEPTH) && YYMAXDEPTH == 0
# undef YYMAXDEPTH
#endif

#ifndef YYMAXDEPTH
# define YYMAXDEPTH 10000
#endif



#if YYERROR_VERBOSE

# ifndef yystrlen
#  if defined (__GLIBC__) && defined (_STRING_H)
#   define yystrlen strlen
#  else
/* Return the length of YYSTR.  */
static YYSIZE_T
#   if defined (__STDC__) || defined (__cplusplus)
yystrlen (const char *yystr)
#   else
yystrlen (yystr)
     const char *yystr;
#   endif
{
  register const char *yys = yystr;

  while (*yys++ != '\0')
    continue;

  return yys - yystr - 1;
}
#  endif
# endif

# ifndef yystpcpy
#  if defined (__GLIBC__) && defined (_STRING_H) && defined (_GNU_SOURCE)
#   define yystpcpy stpcpy
#  else
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
   YYDEST.  */
static char *
#   if defined (__STDC__) || defined (__cplusplus)
yystpcpy (char *yydest, const char *yysrc)
#   else
yystpcpy (yydest, yysrc)
     char *yydest;
     const char *yysrc;
#   endif
{
  register char *yyd = yydest;
  register const char *yys = yysrc;

  while ((*yyd++ = *yys++) != '\0')
    continue;

  return yyd - 1;
}
#  endif
# endif

#endif /* !YYERROR_VERBOSE */



#if YYDEBUG
/*--------------------------------.
| Print this symbol on YYOUTPUT.  |
`--------------------------------*/

#if defined (__STDC__) || defined (__cplusplus)
static void
yysymprint (FILE *yyoutput, int yytype, YYSTYPE *yyvaluep)
#else
static void
yysymprint (yyoutput, yytype, yyvaluep)
    FILE *yyoutput;
    int yytype;
    YYSTYPE *yyvaluep;
#endif
{
  /* Pacify ``unused variable'' warnings.  */
  (void) yyvaluep;

  if (yytype < YYNTOKENS)
    {
      YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
# ifdef YYPRINT
      YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
# endif
    }
  else
    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);

  switch (yytype)
    {
      default:
        break;
    }
  YYFPRINTF (yyoutput, ")");
}

#endif /* ! YYDEBUG */
/*-----------------------------------------------.
| Release the memory associated to this symbol.  |
`-----------------------------------------------*/

#if defined (__STDC__) || defined (__cplusplus)
static void
yydestruct (int yytype, YYSTYPE *yyvaluep)
#else
static void
yydestruct (yytype, yyvaluep)
    int yytype;
    YYSTYPE *yyvaluep;
#endif
{
  /* Pacify ``unused variable'' warnings.  */
  (void) yyvaluep;

  switch (yytype)
    {

      default:
        break;
    }
}


/* Prevent warnings from -Wmissing-prototypes.  */

#ifdef YYPARSE_PARAM
# if defined (__STDC__) || defined (__cplusplus)
int yyparse (void *YYPARSE_PARAM);
# else
int yyparse ();
# endif
#else /* ! YYPARSE_PARAM */
#if defined (__STDC__) || defined (__cplusplus)
int yyparse (void);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */



/* The lookahead symbol.  */
int yychar;

/* The semantic value of the lookahead symbol.  */
YYSTYPE yylval;

/* Number of syntax errors so far.  */
int yynerrs;



/*----------.
| yyparse.  |
`----------*/

#ifdef YYPARSE_PARAM
# if defined (__STDC__) || defined (__cplusplus)
int yyparse (void *YYPARSE_PARAM)
# else
int yyparse (YYPARSE_PARAM)
  void *YYPARSE_PARAM;
# endif
#else /* ! YYPARSE_PARAM */
#if defined (__STDC__) || defined (__cplusplus)
int
yyparse (void)
#else
int
yyparse ()

#endif
#endif
{
  
  register int yystate;
  register int yyn;
  int yyresult;
  /* Number of tokens to shift before error messages enabled.  */
  int yyerrstatus;
  /* Lookahead token as an internal (translated) token number.  */
  int yytoken = 0;

  /* Three stacks and their tools:
     `yyss': related to states,
     `yyvs': related to semantic values,
     `yyls': related to locations.

     Refer to the stacks thru separate pointers, to allow yyoverflow
     to reallocate them elsewhere.  */

  /* The state stack.  */
  short int yyssa[YYINITDEPTH];
  short int *yyss = yyssa;
  register short int *yyssp;

  /* The semantic value stack.  */
  YYSTYPE yyvsa[YYINITDEPTH];
  YYSTYPE *yyvs = yyvsa;
  register YYSTYPE *yyvsp;



#define YYPOPSTACK   (yyvsp--, yyssp--)

  YYSIZE_T yystacksize = YYINITDEPTH;

  /* The variables used to return semantic value and location from the
     action routines.  */
  YYSTYPE yyval;


  /* When reducing, the number of symbols on the RHS of the reduced
     rule.  */
  int yylen;

  YYDPRINTF ((stderr, "Starting parse\n"));

  yystate = 0;
  yyerrstatus = 0;
  yynerrs = 0;
  yychar = YYEMPTY;		/* Cause a token to be read.  */

  /* Initialize stack pointers.
     Waste one element of value and location stack
     so that they stay on the same level as the state stack.
     The wasted elements are never initialized.  */

  yyssp = yyss;
  yyvsp = yyvs;


  goto yysetstate;

/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate.  |
`------------------------------------------------------------*/
 yynewstate:
  /* In all cases, when you get here, the value and location stacks
     have just been pushed. so pushing a state here evens the stacks.
     */
  yyssp++;

 yysetstate:
  *yyssp = yystate;

  if (yyss + yystacksize - 1 <= yyssp)
    {
      /* Get the current used size of the three stacks, in elements.  */
      YYSIZE_T yysize = yyssp - yyss + 1;

#ifdef yyoverflow
      {
	/* Give user a chance to reallocate the stack. Use copies of
	   these so that the &'s don't force the real ones into
	   memory.  */
	YYSTYPE *yyvs1 = yyvs;
	short int *yyss1 = yyss;


	/* Each stack pointer address is followed by the size of the
	   data in use in that stack, in bytes.  This used to be a
	   conditional around just the two extra args, but that might
	   be undefined if yyoverflow is a macro.  */
	yyoverflow ("parser stack overflow",
		    &yyss1, yysize * sizeof (*yyssp),
		    &yyvs1, yysize * sizeof (*yyvsp),

		    &yystacksize);

	yyss = yyss1;
	yyvs = yyvs1;
      }
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
      goto yyoverflowlab;
# else
      /* Extend the stack our own way.  */
      if (YYMAXDEPTH <= yystacksize)
	goto yyoverflowlab;
      yystacksize *= 2;
      if (YYMAXDEPTH < yystacksize)
	yystacksize = YYMAXDEPTH;

      {
	short int *yyss1 = yyss;
	union yyalloc *yyptr =
	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
	if (! yyptr)
	  goto yyoverflowlab;
	YYSTACK_RELOCATE (yyss);
	YYSTACK_RELOCATE (yyvs);

#  undef YYSTACK_RELOCATE
	if (yyss1 != yyssa)
	  YYSTACK_FREE (yyss1);
      }
# endif
#endif /* no yyoverflow */

      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;


      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
		  (unsigned long int) yystacksize));

      if (yyss + yystacksize - 1 <= yyssp)
	YYABORT;
    }

  YYDPRINTF ((stderr, "Entering state %d\n", yystate));

  goto yybackup;

/*-----------.
| yybackup.  |
`-----------*/
yybackup:

/* Do appropriate processing given the current state.  */
/* Read a lookahead token if we need one and don't already have one.  */
/* yyresume: */

  /* First try to decide what to do without reference to lookahead token.  */

  yyn = yypact[yystate];
  if (yyn == YYPACT_NINF)
    goto yydefault;

  /* Not known => get a lookahead token if don't already have one.  */

  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
  if (yychar == YYEMPTY)
    {
      YYDPRINTF ((stderr, "Reading a token: "));
      yychar = YYLEX;
    }

  if (yychar <= YYEOF)
    {
      yychar = yytoken = YYEOF;
      YYDPRINTF ((stderr, "Now at end of input.\n"));
    }
  else
    {
      yytoken = YYTRANSLATE (yychar);
      YYDSYMPRINTF ("Next token is", yytoken, &yylval, &yylloc);
    }

  /* If the proper action on seeing token YYTOKEN is to reduce or to
     detect an error, take that action.  */
  yyn += yytoken;
  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (yyn == 0 || yyn == YYTABLE_NINF)
	goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }

  if (yyn == YYFINAL)
    YYACCEPT;

  /* Shift the lookahead token.  */
  YYDPRINTF ((stderr, "Shifting token %s, ", yytname[yytoken]));

  /* Discard the token being shifted unless it is eof.  */
  if (yychar != YYEOF)
    yychar = YYEMPTY;

  *++yyvsp = yylval;


  /* Count tokens shifted since error; after three, turn off error
     status.  */
  if (yyerrstatus)
    yyerrstatus--;

  yystate = yyn;
  goto yynewstate;


/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state.  |
`-----------------------------------------------------------*/
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;


/*-----------------------------.
| yyreduce -- Do a reduction.  |
`-----------------------------*/
yyreduce:
  /* yyn is the number of a rule to reduce with.  */
  yylen = yyr2[yyn];

  /* If YYLEN is nonzero, implement the default value of the action:
     `$$ = $1'.

     Otherwise, the following line sets YYVAL to garbage.
     This behavior is undocumented and Bison
     users should not rely upon it.  Assigning to YYVAL
     unconditionally makes the parser a bit smaller, and it avoids a
     GCC warning that YYVAL may be used uninitialized.  */
  yyval = yyvsp[1-yylen];


  YY_REDUCE_PRINT (yyn);
  switch (yyn)
    {
        case 2:
#line 650 "maria.y"
    {
	  pnlexreset ();
	;}
    break;

  case 5:
#line 661 "maria.y"
    { pnwarn ("extraneous semicolon"); ;}
    break;

  case 6:
#line 664 "maria.y"
    { pnwarn ("extraneous semicolon"); ;}
    break;

  case 17:
#line 691 "maria.y"
    {
	  if (yyvsp[0].s && getType (yyvsp[0].s)) {
	    thePrinter.printRaw ("ignoring redefinition of type ");
	    thePrinter.printQuoted (yyvsp[0].s);
	    thePrinter.finish ();
	    pnerrors++;
	    deleteType (yyvsp[-1].type); delete[] yyvsp[0].s;
	  }
	  else if (yyvsp[-1].type && yyvsp[0].s) {
	    checkName (yyvsp[0].s, ckType, "invalid type name ");
	    theNet.addType (*yyvsp[-1].type, yyvsp[0].s);
	  }
	  else {
	    deleteType (yyvsp[-1].type); delete[] yyvsp[0].s;
	  }
	;}
    break;

  case 18:
#line 711 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 19:
#line 714 "maria.y"
    { yyval.flag = true; ;}
    break;

  case 20:
#line 717 "maria.y"
    { yyval.flag = yyvsp[-1].flag; pnerror ("ignoring extraneous `queue'"); ;}
    break;

  case 21:
#line 720 "maria.y"
    { yyval.flag = yyvsp[-1].flag; pnerror ("ignoring extraneous `stack'"); ;}
    break;

  case 22:
#line 725 "maria.y"
    {
	  if (!(yyval.type = yyvsp[-1].type))
	    yyval.type = new class StructType (*new class ComponentList);
	;}
    break;

  case 23:
#line 731 "maria.y"
    {
	  if (numberParsed && yyvsp[-1].i > 0)
	    yyval.type = new class IdType (yyvsp[-1].i);
	  else {
	    if (numberParsed)
	      pnerror ("empty identifier pool");
	    yyval.type = NULL;
	  }
	;}
    break;

  case 24:
#line 742 "maria.y"
    { yyval.type = yyvsp[-1].componentList ? new class StructType (*yyvsp[-1].componentList) : NULL; emptyParsed = false; ;}
    break;

  case 25:
#line 745 "maria.y"
    {
	  if (yyvsp[-1].componentList && !yyvsp[-1].componentList->getSize ()) {
	    pnerror ("missing component list for union");
	    delete yyvsp[-1].componentList, yyval.type = NULL;
	  }
	  else
	    yyval.type = yyvsp[-1].componentList ? new class UnionType (*yyvsp[-1].componentList) : NULL;

	  emptyParsed = false;
	;}
    break;

  case 26:
#line 757 "maria.y"
    { yyval.type = yyvsp[0].type; ;}
    break;

  case 27:
#line 760 "maria.y"
    { currentType = yyvsp[0].type; ;}
    break;

  case 28:
#line 762 "maria.y"
    {
	  if ((yyval.type = yyvsp[-2].type) && yyvsp[0].constraint) {
	    yyval.type = copyType (yyval.type);
	    if (class Constraint* c = yyval.type->getConstraint ()) {
	      if (c->isDisjoint (*yyvsp[0].constraint)) {
		pnerror ("ignoring constraint that would make the type empty");
		delete yyvsp[0].constraint;
	      }
	      else
		c->restrict (*yyvsp[0].constraint, *yyval.type);
	    }
	    else
	      yyval.type->setConstraint (*yyvsp[0].constraint);
	  }
 	  else
 	    delete yyvsp[0].constraint;
	  currentType = NULL;
	;}
    break;

  case 29:
#line 782 "maria.y"
    {
	  if (yyvsp[-1].type && !isOrdered (*yyvsp[-1].type)) {
	    deleteType (yyvsp[-3].type), deleteType (yyvsp[-1].type), yyval.type = NULL;
	  }
	  else if (yyvsp[-3].type && yyvsp[-1].type) {
	    card_t size = yyvsp[-1].type->getNumValues ();
	    if (!size || size == CARD_T_MAX || (maxIndex && size > maxIndex)) {
	      thePrinter.printRaw ("type ");
	      printType (*yyvsp[-1].type);
	      thePrinter.printRaw (" has too big domain for indexing");
	      if (size && size < CARD_T_MAX)
		thePrinter.printRaw (" (try -a0)");
	      thePrinter.finish ();
	      pnerrors++;
	      deleteType (yyvsp[-3].type), deleteType (yyvsp[-1].type), yyval.type = NULL;
	    }
	    else {
	      theNet.addType (*yyvsp[-3].type); theNet.addType (*yyvsp[-1].type);
	      yyval.type = new class VectorType (*yyvsp[-3].type, *yyvsp[-1].type);
	    }
	  }
	  else
	    deleteType (yyvsp[-3].type), deleteType (yyvsp[-1].type), yyval.type = NULL;
	;}
    break;

  case 30:
#line 808 "maria.y"
    {
	  if (yyvsp[-4].type && numberParsed) {
	    if (!yyvsp[-1].i) {
	      pnerror ("empty buffer");
	      deleteType (yyvsp[-4].type), yyval.type = NULL;
	    }
	    else {
	      theNet.addType (*yyvsp[-4].type);
	      yyval.type = new class BufferType (*yyvsp[-4].type, yyvsp[-1].i, yyvsp[-2].flag);
	    }
	  }
	  else
	    deleteType (yyvsp[-4].type), yyval.type = NULL;
	;}
    break;

  case 31:
#line 824 "maria.y"
    {
	  pnerror ("array dimension must be an ordered type");
	  deleteType (yyvsp[-3].type), yyval.type = NULL;
	;}
    break;

  case 32:
#line 832 "maria.y"
    { yyval.constraint = yyvsp[-1].constraint; ;}
    break;

  case 33:
#line 837 "maria.y"
    {
 	  if ((yyval.constraint = yyvsp[-2].constraint) && yyvsp[0].range)
 	    yyval.constraint->append (*yyvsp[0].range);
 	  else
	    delete yyvsp[0].range;
	;}
    break;

  case 34:
#line 845 "maria.y"
    { if (yyvsp[0].range) (yyval.constraint = new class Constraint)->append (*yyvsp[0].range); else yyval.constraint = NULL; ;}
    break;

  case 35:
#line 850 "maria.y"
    { yyval.range = yyvsp[0].value ? new class Range (*yyvsp[0].value, *yyvsp[0].value) : NULL; ;}
    break;

  case 36:
#line 853 "maria.y"
    { yyval.range = yyvsp[0].value ? new class Range (currentType->getFirstValue (), *yyvsp[0].value) : 0; ;}
    break;

  case 37:
#line 856 "maria.y"
    {
 	  if (yyvsp[-2].value && yyvsp[0].value) {
	    if (pnwarnings && *yyvsp[0].value < *yyvsp[-2].value)
	      pnwarn ("upper limit of range specified before lower limit");
 	    yyval.range = new class Range (*yyvsp[-2].value, *yyvsp[0].value);
	  }
	  else {
	    yyval.range = NULL; delete yyvsp[-2].value; delete yyvsp[0].value;
	  }
	;}
    break;

  case 38:
#line 868 "maria.y"
    { yyval.range = yyvsp[-1].value ? new class Range (*yyvsp[-1].value, currentType->getLastValue ()) : 0; ;}
    break;

  case 39:
#line 873 "maria.y"
    { yyval.value = ensureConstant (yyvsp[0].expr, currentType); ;}
    break;

  case 40:
#line 878 "maria.y"
    { yyval.value = ensureConstant (yyvsp[0].expr, currentType); ;}
    break;

  case 41:
#line 883 "maria.y"
    {
	  if (!yyvsp[0].s) yyval.type = NULL;
	  else if ((yyval.type = const_cast<class Type*>(getType (yyvsp[0].s))));
	  else if (!strcmp (yyvsp[0].s, "bool"))
	    yyval.type = &const_cast<class BoolType&>(Net::getBoolType ());
	  else if (!strcmp (yyvsp[0].s, "int"))
	    yyval.type = &const_cast<class IntType&>(Net::getIntType ());
	  else if (!strcmp (yyvsp[0].s, "unsigned"))
	    yyval.type = &const_cast<class CardType&>(Net::getCardType ());
	  else if (!strcmp (yyvsp[0].s, "char"))
	    yyval.type = &const_cast<class CharType&>(Net::getCharType ());
	  else {
	    thePrinter.printRaw ("undefined type ");
	    thePrinter.printQuoted (yyvsp[0].s);
	    thePrinter.finish ();
	    pnerrors++;
	  }
	  delete[] yyvsp[0].s;
	;}
    break;

  case 42:
#line 906 "maria.y"
    {
	  yyval.i = 0; numberParsed = false;

	  if (yyvsp[0].expr && yyvsp[0].expr->getType () && (yyvsp[0].expr = fold (yyvsp[0].expr)) &&
	      yyvsp[0].expr->getKind () == Expression::eConstant) {
	    const class Valuation empty;
	    class Value* v = yyvsp[0].expr->eval (empty);
	    assert (v && yyvsp[0].expr->getType ()->isConstrained (*v));
	    switch (v->getType ().getKind ()) {
	    case Type::tChar:
	      yyval.i = char_t (static_cast<const class LeafValue&>(*v));
	      if (pnwarnings) {
		thePrinter.printRaw ("Warning:converting ");
		thePrinter.print (char_t (yyval.i));
		thePrinter.printRaw (" to ");
		thePrinter.print (yyval.i);
		thePrinter.finish ();
	      }
	      break;
	    case Type::tInt:
	      numberParsed = true;
	      yyval.i = int_t (static_cast<const class LeafValue&>(*v));
	      if (pnwarnings) {
		thePrinter.printRaw ("Warning:converting ");
		thePrinter.print (int_t (yyval.i));
		thePrinter.printRaw (" to ");
		thePrinter.print (yyval.i);
		thePrinter.finish ();
	      }
	      break;
	    case Type::tCard:
	      numberParsed = true;
	      yyval.i = card_t (static_cast<const class LeafValue&>(*v));
	      break;
	    case Type::tEnum:
	      numberParsed = true;
	      yyval.i = card_t (static_cast<const class LeafValue&>(*v));
	      break;
	    default:
	      pnerror ("expression does not evaluate to a number");
	      break;
	    }

	    delete v;
	  }
	  else if (yyvsp[0].expr)
	    pnerror ("number expected, got expression");

	  yyvsp[0].expr->destroy ();
	;}
    break;

  case 43:
#line 960 "maria.y"
    { yyval.s = yyvsp[0].s; ;}
    break;

  case 44:
#line 963 "maria.y"
    { yyval.s = NULL; ;}
    break;

  case 45:
#line 967 "maria.y"
    { yyval.s = NULL; ;}
    break;

  case 46:
#line 970 "maria.y"
    { yyval.s = yyvsp[0].s; ;}
    break;

  case 47:
#line 974 "maria.y"
    { pnerror ("missing name"); yyval.s = NULL; ;}
    break;

  case 48:
#line 977 "maria.y"
    { yyval.s = yyvsp[0].s; ;}
    break;

  case 49:
#line 982 "maria.y"
    {
	  if ((yyval.s = yyvsp[0].s))
	    checkName (yyval.s, ckEnum, "invalid enumeration constant name ");
	;}
    break;

  case 52:
#line 994 "maria.y"
    { yyval.type = NULL; pnerror ("missing enumeration value"); ;}
    break;

  case 53:
#line 997 "maria.y"
    {
	  if (yyvsp[0].s)
	    addEnumeration (static_cast<class EnumType*>(yyval.type =
							 new class EnumType),
			    yyvsp[0].s);
	  else
	    yyval.type = NULL;
	;}
    break;

  case 54:
#line 1007 "maria.y"
    {
	  if (!(yyval.type = yyvsp[-2].type) && yyvsp[0].s)
	    addEnumeration (static_cast<class EnumType*>(yyval.type =
							 new class EnumType),
			    yyvsp[0].s);
	  else if (yyval.type && yyvsp[0].s)
	    addEnumeration (static_cast<class EnumType*>(yyval.type), yyvsp[0].s);
	;}
    break;

  case 55:
#line 1017 "maria.y"
    {
	  if (yyvsp[-2].s && numberParsed)
	    addEnumeration (static_cast<class EnumType*>(yyval.type =
							 new class EnumType),
			    yyvsp[-2].s, yyvsp[0].i);
	  else {
	    yyval.type = NULL; delete[] yyvsp[-2].s;
	  }
	;}
    break;

  case 56:
#line 1028 "maria.y"
    {
	  if (!numberParsed) {
	    yyval.type = yyvsp[-4].type; delete[] yyvsp[-2].s;
	  }
	  else if (!(yyval.type = yyvsp[-4].type) && yyvsp[-2].s)
	    addEnumeration (static_cast<class EnumType*>(yyval.type =
							 new class EnumType),
			    yyvsp[-2].s, yyvsp[0].i);
	  else if (yyval.type && yyvsp[-2].s)
	    addEnumeration (static_cast<class EnumType*>(yyval.type), yyvsp[-2].s, yyvsp[0].i);
	;}
    break;

  case 59:
#line 1045 "maria.y"
    {
	  if ((yyval.s = yyvsp[0].s))
	    checkName (yyval.s, ckComp, "invalid component name ");
	;}
    break;

  case 60:
#line 1053 "maria.y"
    {
	  if (yyvsp[-1].type && yyvsp[0].s) {
	    (yyval.componentList = new class ComponentList)->addComponent (yyvsp[0].s, *yyvsp[-1].type);
	    theNet.addType (*yyvsp[-1].type);
	  }
	  else {
	    deleteType (yyvsp[-1].type);
	    delete[] yyvsp[0].s;
	    yyval.componentList = NULL;
	  }

	  emptyParsed = false;
	;}
    break;

  case 61:
#line 1068 "maria.y"
    {
	  if ((yyval.componentList = yyvsp[-3].componentList) && yyvsp[-1].type && yyvsp[0].s) {
	    if (emptyParsed)
	      pnerror ("extraneous delimiter in component list");

	    emptyParsed = false;

	    if ((*yyval.componentList)[yyvsp[0].s]) {
	      thePrinter.printRaw ("ignoring redefinition of component ");
	      thePrinter.printQuoted (yyvsp[0].s);
	      thePrinter.finish ();
	      pnerrors++;
	      deleteType (yyvsp[-1].type);
	      delete[] yyvsp[0].s;
	    }
	    else {
	      yyval.componentList->addComponent (yyvsp[0].s, *yyvsp[-1].type);
	      theNet.addType (*yyvsp[-1].type);
	    }
	  }
	  else {
	    delete yyval.componentList;
	    deleteType (yyvsp[-1].type);
	    delete[] yyvsp[0].s;
	    yyval.componentList = NULL;
	  }
	;}
    break;

  case 62:
#line 1097 "maria.y"
    {
	  yyval.componentList = yyvsp[-1].componentList;
	  if (emptyParsed)
	    pnerror ("extraneous delimiter in component list");
	  emptyParsed = true;
	;}
    break;

  case 63:
#line 1104 "maria.y"
    { yyval.componentList = new class ComponentList; emptyParsed = true; ;}
    break;

  case 66:
#line 1115 "maria.y"
    {
	  if ((yyval.s = yyvsp[0].s))
	    checkName (yyvsp[0].s, ckFunc, "invalid function name ");
	;}
    break;

  case 67:
#line 1123 "maria.y"
    { currentType = yyvsp[-2].type; ;}
    break;

  case 68:
#line 1125 "maria.y"
    { defun (yyvsp[-4].type, yyvsp[-3].s, yyvsp[0].expr); ;}
    break;

  case 69:
#line 1128 "maria.y"
    {
	  currentType = yyvsp[-4].type;
	  if (emptyParsed && currentArity)
	    pnerror ("extraneous delimiter after formal parameter list");
	  emptyParsed = false;
	;}
    break;

  case 70:
#line 1135 "maria.y"
    { defun (yyvsp[-6].type, yyvsp[-5].s, yyvsp[0].expr); ;}
    break;

  case 71:
#line 1140 "maria.y"
    {
	  if (currentArity || currentParameters)
	    delete[] yyvsp[0].s;
	  else
	    addParameter (yyvsp[-1].type, yyvsp[0].s), emptyParsed = false;
	;}
    break;

  case 72:
#line 1148 "maria.y"
    {
	  if (yyvsp[-1].type && yyvsp[0].s && emptyParsed)
	    pnerror ("extraneous delimiter in parameter list");
	  addParameter (yyvsp[-1].type, yyvsp[0].s);
	  emptyParsed = false;
	;}
    break;

  case 73:
#line 1156 "maria.y"
    {
	  if (emptyParsed)
	    pnerror ("extraneous delimiter in parameter list");
	  emptyParsed = true;
	;}
    break;

  case 74:
#line 1162 "maria.y"
    { if (!currentArity && !currentParameters) emptyParsed = true; ;}
    break;

  case 75:
#line 1166 "maria.y"
    { yyval.constraint = NULL; ;}
    break;

  case 76:
#line 1169 "maria.y"
    { currentType = &Net::getCardType (); ;}
    break;

  case 77:
#line 1171 "maria.y"
    {
	  if (!(yyval.constraint = yyvsp[-2].constraint))
	    yyval.constraint = yyvsp[0].constraint;
	  else {
	    if (yyval.constraint->isDisjoint (*yyvsp[0].constraint)) {
	      pnerror ("ignoring contradictory capacity constraint");
	      delete yyvsp[-2].constraint; delete yyvsp[0].constraint;
	      yyval.constraint = NULL;
	    }
	    else {
	      yyval.constraint->restrict (*yyvsp[0].constraint, *currentType); delete yyvsp[0].constraint;
	    }
	  }
	  currentType = NULL;
	;}
    break;

  case 78:
#line 1189 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 79:
#line 1192 "maria.y"
    { if (yyvsp[-1].flag) pnerror ("ignoring extraneous `const'"); yyval.flag = true; ;}
    break;

  case 80:
#line 1197 "maria.y"
    {
	  currentPlace = NULL;
	  if ((currentType = yyvsp[-1].type))
	    theNet.addType (*yyvsp[-1].type);

	  if (yyvsp[-3].s && yyvsp[-1].type) {
	    if (theNet.getPlace (yyvsp[-3].s)) {
	      thePrinter.printRaw ("ignoring redefinition of place ");
	      thePrinter.printQuoted (yyvsp[-3].s);
	      thePrinter.finish ();
	      pnerrors++;
	      delete[] yyvsp[-3].s; delete yyvsp[-2].constraint;
	    }
	    else {
	      checkName (yyvsp[-3].s, ckPlace, "invalid place name ");
	      (currentPlace = &theNet.addPlace (yyvsp[-3].s, yyvsp[-2].constraint, *yyvsp[-1].type))
		->setConstant (yyvsp[0].flag);
	    }
	  }
	  else {
	    delete[] yyvsp[-3].s; delete yyvsp[-2].constraint;
	  }
	;}
    break;

  case 81:
#line 1221 "maria.y"
    {
	  if (currentPlace && yyvsp[0].marking)
	    currentPlace->setInitMarking (*yyvsp[0].marking);
	  else
	    yyvsp[0].marking->destroy ();
	  currentType = NULL, currentPlace = NULL;
	;}
    break;

  case 82:
#line 1232 "maria.y"
    {
	  if (yyvsp[0].s) {
	    if (!(yyval.place = const_cast<class Place*>(theNet.getPlace (yyvsp[0].s)))) {
	      thePrinter.printRaw ("undefined place ");
	      thePrinter.printQuoted (yyvsp[0].s);
	      thePrinter.finish ();
	      pnerrors++;
	    }
	  }
	  else
	    yyval.place = NULL;
	  delete[] yyvsp[0].s;
	;}
    break;

  case 83:
#line 1248 "maria.y"
    { yyval.marking = NULL; ;}
    break;

  case 84:
#line 1251 "maria.y"
    {
	  if (!(yyval.marking = yyvsp[-2].marking))
	    yyval.marking = yyvsp[0].marking;
	  else {
	    pnerror ("multiple init blocks"); yyvsp[0].marking->destroy ();
	  }
	;}
    break;

  case 85:
#line 1261 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 86:
#line 1264 "maria.y"
    { if (yyvsp[-1].flag) pnerror ("ignoring extraneous `:'"); yyval.flag = true; ;}
    break;

  case 87:
#line 1268 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 88:
#line 1271 "maria.y"
    { if (yyvsp[-1].flag) pnerror ("ignoring extraneous `!'"); yyval.flag = true; ;}
    break;

  case 89:
#line 1276 "maria.y"
    {
	  if (yyvsp[-1].s) {
	    if ((currentTransition = yyvsp[-2].flag
		 ? theNet.getCallee (yyvsp[-1].s, 0)
		 : theNet.getTransition (yyvsp[-1].s))) {
	      pnwarn ("augmenting transition definition");
	      delete[] yyvsp[-1].s;
	    }
	    else {
	      if (!yyvsp[-2].flag) checkName (yyvsp[-1].s, ckTrans, "invalid transition name ");
	      currentTransition = &theNet.addTransition (yyvsp[-1].s, yyvsp[-2].flag);
	    }
	    if (yyvsp[0].flag)
	      currentTransition->setPriority (theNet.getMaxPriority ());
	  }
	  else
	    currentTransition = NULL;
	;}
    break;

  case 90:
#line 1295 "maria.y"
    {
	  if (currentTransition && !yyvsp[-4].flag) {
	    if (const class QuantifierList* q =
		currentTransition->getOutputVariables ()) {
	      for (QuantifierList::const_iterator i = q->begin ();
		   i != q->end (); i++) {
		const class VariableDefinition& v = (*i)->getVariable ();

		if (currentTransition->isInput (&v)) {
		  thePrinter.printRaw ("output variable ");
		  thePrinter.printQuoted (v.getName ());
		  thePrinter.printRaw (" encountered on an input arc");
		  thePrinter.finish ();
		  pnerrors++;
		}
		if (currentTransition->isGate (&v)) {
		  thePrinter.printRaw ("output variable ");
		  thePrinter.printQuoted (v.getName ());
		  thePrinter.printRaw (" encountered on a gate");
		  thePrinter.finish ();
		  pnerrors++;
		}
		if (!currentTransition->isOutput (&v)) {
		  thePrinter.printRaw ("output variable ");
		  thePrinter.printQuoted (v.getName ());
		  thePrinter.printRaw (" not used on output arcs");
		  thePrinter.finish ();
		  pnerrors++;
		}
	      }
	    }
	    if (currentTransition->isInput (0)) {
	      thePrinter.printRaw ("an input arc refers to place contents");
	      thePrinter.finish ();
	      pnerrors++;
	    }
	    if (currentTransition->isGate (0)) {
	      thePrinter.printRaw ("a gate refers to place contents");
	      thePrinter.finish ();
	      pnerrors++;
	    }
	    if (!currentTransition->hasInputs () &&
		currentTransition->hasOutputs ())
	      pnwarn ("transition has output arcs but no inputs");
	    if (!currentTransition->isUnifiable (net->getParent ()
						 ? Transition::uIgnore
						 : Transition::uNormal,
						 thePrinter))
	      pnerror ("transition cannot be unified");
	  }
	  currentTransition = NULL;
	;}
    break;

  case 91:
#line 1351 "maria.y"
    {
	  if (yyvsp[0].s) {
	    if (!(yyval.trans = const_cast<class Transition*>(theNet.getTransition
						     (yyvsp[0].s)))) {
	      thePrinter.printRaw ("undefined transition ");
	      thePrinter.printQuoted (yyvsp[0].s);
	      thePrinter.finish ();
	      pnerrors++;
	    }
	  }
	  else
	    yyval.trans = NULL;
	  delete[] yyvsp[0].s;
	;}
    break;

  case 94:
#line 1372 "maria.y"
    { isOutputArc = false; ;}
    break;

  case 96:
#line 1376 "maria.y"
    { isOutputArc = true; ;}
    break;

  case 98:
#line 1380 "maria.y"
    { currentType = &Net::getBoolType (); ;}
    break;

  case 99:
#line 1382 "maria.y"
    { currentType = NULL; ;}
    break;

  case 100:
#line 1385 "maria.y"
    { currentContextTransition = currentTransition; ;}
    break;

  case 101:
#line 1387 "maria.y"
    {
	  if (currentTransition &&
	      ((yyvsp[0].expr && yyvsp[0].expr->getKind () == Expression::eMarking &&
		yyvsp[0].expr->getType () && yyvsp[0].expr->getType ()->getKind () == Type::tBool) ||
	      (yyvsp[0].expr = ensureBool (ensureExpr (yyvsp[0].expr))))) {
	    if (!theNet.addConstraint (*yyvsp[0].expr->cse (), *currentTransition,
				       static_cast<enum Net::CKind>(yyvsp[-2].i)))
	      pnerror ("error in constraint");
	  }
	  else
	    yyvsp[0].expr->destroy ();
	  currentContextTransition = NULL;
	;}
    break;

  case 102:
#line 1402 "maria.y"
    { currentContextTransition = currentTransition; ;}
    break;

  case 103:
#line 1404 "maria.y"
    {
	  if (currentTransition && (yyvsp[0].expr = ensureBool (yyvsp[0].expr)))
	    currentTransition->addHide (*yyvsp[0].expr->cse ());
	  else
	    yyvsp[0].expr->destroy ();
	  currentContextTransition = NULL;
	;}
    break;

  case 104:
#line 1413 "maria.y"
    {
	  if (!currentTransition || !yyvsp[0].s);
	  else if (const class Transition* t =
		   theNet.getCallee (yyvsp[0].s, currentTransition)) {
	    if (!currentTransition->fuse (*t, thePrinter, pnwarnings))
	      pnerrors++;
	  }
	  else {
	    thePrinter.printRaw (":trans ");
	    thePrinter.printQuoted (yyvsp[0].s);
	    thePrinter.printRaw (" not found");
	    thePrinter.finish ();
	    pnerrors++;
	  }
	  delete[] yyvsp[0].s;
	;}
    break;

  case 105:
#line 1431 "maria.y"
    {
	  if (pnwarnings && currentTransition &&
	      currentTransition->getPriority ()) {
	    thePrinter.printRaw ("redefining priority");
	    thePrinter.finish ();
	  }
	  if (currentTransition) currentTransition->setPriority (yyvsp[0].i);
	;}
    break;

  case 106:
#line 1442 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 107:
#line 1445 "maria.y"
    { yyval.flag = true; ;}
    break;

  case 108:
#line 1448 "maria.y"
    {
	  if (!yyvsp[-2].flag)
	    pnerror ("extraneous delimiter before variable definition");
	  yyval.flag = true;
	;}
    break;

  case 109:
#line 1455 "maria.y"
    {
	  if (!yyvsp[-1].flag)
	    pnerror ("extraneous delimiter in variable definition list");
	  yyval.flag = false;
	;}
    break;

  case 110:
#line 1464 "maria.y"
    {
	  if (yyvsp[-1].type && yyvsp[0].s && currentTransition) {
	    if (currentTransition->getVariable (yyvsp[0].s)) {
	      thePrinter.printRaw ("redefinition of variable ");
	      thePrinter.printQuoted (yyvsp[0].s);
	      thePrinter.finish ();
	      pnerrors++;
	      delete[] yyvsp[0].s;
	    }
	    else {
	      currentTransition->addVariable (yyvsp[0].s, *yyvsp[-1].type, false, yyvsp[-2].flag);
	      checkName (yyvsp[0].s, ckVar, "invalid variable name ");
	      if (pnwarnings) {
		if (getConstant (yyvsp[0].s) || getConstantFunction (yyvsp[0].s)) {
		  thePrinter.printRaw ("Warning:variable ");
		  thePrinter.printQuoted (yyvsp[0].s);
		  thePrinter.printRaw (" shadows a constant");
		  thePrinter.finish ();
		}
		else if (getType (yyvsp[0].s)) {
		  thePrinter.printRaw ("Warning:variable ");
		  thePrinter.printQuoted (yyvsp[0].s);
		  thePrinter.printRaw (" shadows a type name");
		  thePrinter.finish ();
		}
	      }
	    }
	  }
	  else
	    delete[] yyvsp[0].s;
	;}
    break;

  case 111:
#line 1497 "maria.y"
    { beginAny (yyvsp[-2].type, yyvsp[-1].s, yyvsp[-3].flag); ;}
    break;

  case 112:
#line 1499 "maria.y"
    { endAny (yyvsp[-4].type, yyvsp[-3].s, yyvsp[0].expr)->destroy (); ;}
    break;

  case 113:
#line 1502 "maria.y"
    { if (yyvsp[-1].flag) pnerror ("ignoring meaningless `hide'"); ;}
    break;

  case 114:
#line 1506 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 115:
#line 1509 "maria.y"
    { yyval.flag = true; if (yyvsp[-1].flag) pnerror ("ignoring extraneous `hide'"); ;}
    break;

  case 120:
#line 1525 "maria.y"
    {;}
    break;

  case 121:
#line 1528 "maria.y"
    {
	  currentType = (currentPlace = yyvsp[-1].place) ? &yyvsp[-1].place->getType () : NULL;
	;}
    break;

  case 122:
#line 1532 "maria.y"
    {
	  if (!currentPlace || !currentTransition)
	    yyvsp[0].marking->destroy ();
	  else if (yyvsp[0].marking) {
	    if (class Arc* arc =
		currentTransition->getArc (isOutputArc, *currentPlace)) {
	      if (pnwarnings) {
		thePrinter.printRaw ("Warning:extending arc ");
		thePrinter.printRaw (isOutputArc
				     ? "to place "
				     : "from place ");
		thePrinter.printQuoted (currentPlace->getName ());
		thePrinter.finish ();
	      }
	      arc->append (*yyvsp[0].marking);
	    }
	    else if (isOutputArc && currentTransition->getKind ())
	      yyvsp[0].marking->destroy ();
	    else
	      currentTransition->addArc (*new class Arc
					 (isOutputArc, *yyvsp[0].marking, *currentPlace));
	  }
	  currentPlace = NULL, currentType = NULL;
	;}
    break;

  case 123:
#line 1559 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 124:
#line 1562 "maria.y"
    { yyval.flag = true; if (yyvsp[-1].flag) pnerror ("ignoring extraneous `place'"); ;}
    break;

  case 125:
#line 1565 "maria.y"
    { yyval.flag = yyvsp[-1].flag; pnerror ("expected `place', got `trans'"); ;}
    break;

  case 127:
#line 1572 "maria.y"
    { pnerror ("ignoring extraneous `place'"); ;}
    break;

  case 128:
#line 1575 "maria.y"
    { pnerror ("ignoring extraneous `trans'"); ;}
    break;

  case 129:
#line 1579 "maria.y"
    { yyval.flag = false; ;}
    break;

  case 130:
#line 1582 "maria.y"
    { yyval.flag = true; if (yyvsp[-1].flag) pnerror ("ignoring extraneous `trans'"); ;}
    break;

  case 131:
#line 1585 "maria.y"
    { yyval.flag = yyvsp[-1].flag; pnerror ("expected `trans', got `place'"); ;}
    break;

  case 133:
#line 1592 "maria.y"
    { pnerror ("ignoring extraneous `trans'"); ;}
    break;

  case 134:
#line 1595 "maria.y"
    { pnerror ("ignoring extraneous `place' after `trans'"); ;}
    break;

  case 137:
#line 1606 "maria.y"
    {
	  if ((yyvsp[0].expr = ensureBool (ensureExpr (yyvsp[0].expr), true)) && currentTransition) {
	    if (yyvsp[0].expr->getKind () == Expression::eConstant) {
	      const class Value& v =
		static_cast<const class Constant*>(yyvsp[0].expr)->getValue ();
	      assert (v.getKind () == Value::vLeaf);
	      if (bool (static_cast<const class LeafValue&>(v))) {
		pnwarn ("gate is constantly enabled");
		yyvsp[0].expr->destroy ();
	      }
	      else {
		pnwarn ("gate is constantly disabled");
		currentTransition->addGate (*yyvsp[0].expr);
	      }
	    }
	    else if (yyvsp[0].expr->getKind () == Expression::eUndefined) {
	      if (currentTransition->getKind ())
		pnwarn ("multiple 'fatal' or 'undefined' gates");
	      currentTransition->setAssertion
		(static_cast<class Undefined*>(yyvsp[0].expr)->isFatal ());
	      yyvsp[0].expr->destroy ();
	    }
	    else
	      currentTransition->addGate (*yyvsp[0].expr);
	  }
	  else
	    yyvsp[0].expr->destroy ();
	;}
    break;

  case 138:
#line 1638 "maria.y"
    { if ((yyvsp[0].expr = ensureBool (yyvsp[0].expr, true))) theNet.addReject (*yyvsp[0].expr); ;}
    break;

  case 139:
#line 1641 "maria.y"
    { if ((yyvsp[0].expr = ensureBool (yyvsp[0].expr, true))) theNet.addDeadlock (*yyvsp[0].expr); ;}
    break;

  case 140:
#line 1646 "maria.y"
    {
	  if ((yyvsp[0].expr = ensureBool (yyvsp[0].expr)) && yyvsp[-2].s) {
	    if (!theNet.addProp (yyvsp[-2].s, *yyvsp[0].expr)) {
	      thePrinter.printRaw ("redefinition of state proposition ");
	      thePrinter.printQuoted (yyvsp[-2].s);
	      thePrinter.finish ();
	      pnerrors++;
	      delete[] yyvsp[-2].s;
	      yyvsp[0].expr->destroy ();
	    }
	  }
	  else {
	    delete[] yyvsp[-2].s; yyvsp[0].expr->destroy ();
	  }
	;}
    break;

  case 141:
#line 1665 "maria.y"
    {
	  if (net) {
	    class Net& child = net->addChild (yyvsp[-1].s);
	    net = &child;
	  }
	  else
	    delete[] yyvsp[-1].s;
	;}
    break;

  case 142:
#line 1674 "maria.y"
    {
	  if (net && net->getParent ()) {
	    if (!net->computeInitMarking (thePrinter)) {
	      thePrinter.printRaw ("error in the initial marking");
	      thePrinter.finish ();
	      pnerrors++;
	    }
	    net = net->getParent ();
	  }
	;}
    break;

  case 143:
#line 1686 "maria.y"
    { delete[] yyvsp[-2].s; ;}
    break;

  case 144:
#line 1691 "maria.y"
    { isFairnessStrong = static_cast<enum Net::CKind>(yyvsp[0].i); ;}
    break;

  case 145:
#line 1693 "maria.y"
    {;}
    break;

  case 146:
#line 1698 "maria.y"
    { yyval.i = 0; ;}
    break;

  case 147:
#line 1701 "maria.y"
    { yyval.i = 1; ;}
    break;

  case 148:
#line 1704 "maria.y"
    { yyval.i = 2; ;}
    break;

  case 149:
#line 1707 "maria.y"
    { yyval.i = yyvsp[-1].i; pnerror ("ignoring extraneous `weakly_fair'"); ;}
    break;

  case 150:
#line 1710 "maria.y"
    { yyval.i = yyvsp[-1].i; pnerror ("ignoring extraneous `strongly_fair'"); ;}
    break;

  case 151:
#line 1713 "maria.y"
    { yyval.i = yyvsp[-1].i; pnerror ("ignoring extraneous `enabled'"); ;}
    break;

  case 154:
#line 1724 "maria.y"
    {
	  if (yyvsp[0].expr && !theNet.addConstraint (*yyvsp[0].expr, isFairnessStrong))
	    pnerror ("error in constraint");
	;}
    break;

  case 155:
#line 1732 "maria.y"
    { yyval.marking = ensureMarking (yyvsp[0].expr, currentType); ;}
    break;

  case 156:
#line 1737 "maria.y"
    { yyval.marking = yyvsp[0].marking; ;}
    break;

  case 157:
#line 1740 "maria.y"
    {
	  if ((yyval.marking = yyvsp[-2].marking) && yyvsp[0].marking)
	    yyval.marking->append (*yyvsp[0].marking);
	  else if (yyvsp[0].marking)
	    yyval.marking = yyvsp[0].marking;
	;}
    break;

  case 158:
#line 1750 "maria.y"
    { yyval.expr = yyvsp[0].expr; ;}
    break;

  case 159:
#line 1753 "maria.y"
    { yyvsp[-1].expr = ensureMarking (yyvsp[-1].expr, currentType); ;}
    break;

  case 160:
#line 1755 "maria.y"
    {
	  assert (!yyvsp[-3].expr || yyvsp[-3].expr->getKind () == Expression::eMarking);
	  if ((yyval.expr = yyvsp[-3].expr) && yyvsp[0].marking)
	    static_cast<class Marking*>(yyval.expr)->append (*yyvsp[0].marking);
	  else if (yyvsp[0].marking)
	    yyval.expr = yyvsp[0].marking;
	;}
    break;

  case 161:
#line 1765 "maria.y"
    { yyval.expr = NULL; ;}
    break;

  case 162:
#line 1768 "maria.y"
    { yyval.expr = yyvsp[-1].expr; ;}
    break;

  case 163:
#line 1772 "maria.y"
    { yyval.expr = NULL; ;}
    break;

  case 164:
#line 1775 "maria.y"
    { yyval.expr = yyvsp[0].expr; ;}
    break;

  case 165:
#line 1778 "maria.y"
    { yyval.expr = namedComponent (yyvsp[-1].s, NULL); ;}
    break;

  case 166:
#line 1781 "maria.y"
    { yyval.expr = namedComponent (yyvsp[-2].s, yyvsp[0].expr); ;}
    break;

  case 167:
#line 1786 "maria.y"
    {
	  if (currentContextType && !YYRECOVERING ()) {
	    assert (!currentComponent);

	    switch (currentContextType->getKind ()) {
	    case Type::tVector:
	      {
		const class VectorType* type =
		  static_cast<const class VectorType*>(currentContextType);
		class VectorExpression* v = new class VectorExpression (*type);

		if (!yyvsp[0].expr) {
		  pnerror ("missing expression for first vector component");
		  v->destroy (), yyval.expr = NULL;
		}
		else if (isCompatible (yyvsp[0].expr, currentType))
		  yyval.expr = v, v->setComponent (currentComponent, *yyvsp[0].expr);
		else
		  v->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
	      }
	      break;
	    case Type::tBuffer:
	      {
		const class BufferType* type =
		  static_cast<const class BufferType*>(currentContextType);
		class BufferExpression* b = new class BufferExpression (*type);

		if (!yyvsp[0].expr)
		  yyval.expr = b;
		else if (isCompatible (yyvsp[0].expr, currentType))
		  yyval.expr = b, b->append (*yyvsp[0].expr);
		else
		  b->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
	      }
	      break;
	    case Type::tStruct:
	      {
		if (!yyvsp[0].expr &&
		    !static_cast<const class StructType*>(currentContextType)
		    ->getSize ())
		  yyval.expr = (new class Constant (*new class StructValue
					    (*currentContextType)))->cse ();
		else {
		  class StructExpression* s =
		    new class StructExpression (*currentContextType);

		  if (isCompatible (yyvsp[0].expr, *s))
		    yyval.expr = s, s->append (*yyvsp[0].expr), currentType = s->getNextType ();
		  else
		    s->destroy (), yyvsp[0].expr->destroy (),
		      yyval.expr = NULL, currentType = NULL;
		}
	      }
	      break;
	    default:
	      assert (false);
	    }
	  }
	  else
	    yyvsp[0].expr->destroy (), yyval.expr = NULL;

	  currentComponent++;
	;}
    break;

  case 168:
#line 1851 "maria.y"
    {
	  if ((yyval.expr = yyvsp[-2].expr) && currentContextType && !YYRECOVERING ()) {
	    assert (currentComponent > 0);
	    switch (currentContextType->getKind ()) {
	    case Type::tVector:
	      {
		assert (yyval.expr->getKind () == Expression::eVector);
		class VectorExpression* v =
		  static_cast<class VectorExpression*>(yyval.expr);
		const class VectorType* type =
		  static_cast<const class VectorType*>(currentContextType);

		if (currentComponent < type->getSize ()) {
		  if (!yyvsp[0].expr) {
		    thePrinter.printRaw ("missing array item ");
		    thePrinter.print (currentComponent);
		    thePrinter.finish ();
		    pnerrors++;
		    yyval.expr->destroy (), yyval.expr = NULL;
		  }
		  else if (isCompatible (yyvsp[0].expr, currentType))
		    v->setComponent (currentComponent, *yyvsp[0].expr);
		  else
		    yyval.expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
		}
		else {
		  thePrinter.printRaw ("too many items for array ");
		  printType (*type);
		  thePrinter.finish ();
		  pnerrors++;
		  yyval.expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
		}
	      }
	      break;
	    case Type::tBuffer:
	      {
		assert (yyval.expr->getKind () == Expression::eBuffer);
		class BufferExpression* b =
		  static_cast<class BufferExpression*>(yyval.expr);
		const class BufferType* type =
		  static_cast<const class BufferType*>(currentContextType);

		if (b->hasCapacity ()) {
		  if (!yyvsp[0].expr || !b->getSize ()) {
		    thePrinter.printRaw ("missing buffer item ");
		    thePrinter.print (yyvsp[0].expr ? currentComponent : 0);
		    thePrinter.finish ();
		    pnerrors++;
		    yyval.expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
		  }
		  else if (isCompatible (yyvsp[0].expr, currentType))
		    b->append (*yyvsp[0].expr);
		  else
		    yyval.expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
		}
		else {
		  thePrinter.printRaw ("too many items for buffer ");
		  printType (*type);
		  thePrinter.finish ();
		  pnerrors++;
		  yyval.expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
		}
	      }
	      break;
	    case Type::tStruct:
	      {
		assert (yyval.expr->getKind () == Expression::eStruct);
		class StructExpression* s =
		  static_cast<class StructExpression*>(yyval.expr);

		if (isCompatible (yyvsp[0].expr, *s))
		  s->append (*yyvsp[0].expr), currentType = s->getNextType ();
		else
		  yyval.expr->destroy (), yyvsp[0].expr->destroy (),
		    yyval.expr = NULL, currentType = NULL;
	      }
	      break;
	    default:
	      assert (false);
	    }
	  }
	  else
	    yyval.expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;

	  currentComponent++;
	;}
    break;

  case 169:
#line 1940 "maria.y"
    { yyval.expr = NULL; pnerror ("missing expression"); ;}
    break;

  case 170:
#line 1943 "maria.y"
    { yyval.expr = yyvsp[0].expr; ;}
    break;

  case 171:
#line 1948 "maria.y"
    { yyval.expr = ensureExpr (yyvsp[0].expr); ;}
    break;

  case 172:
#line 1953 "maria.y"
    { yyval.i = 0; ;}
    break;

  case 173:
#line 1956 "maria.y"
    { yyval.i = 1; ;}
    break;

  case 174:
#line 1959 "maria.y"
    { yyval.i = 2; ;}
    break;

  case 175:
#line 1962 "maria.y"
    { yyval.i = 3; ;}
    break;

  case 176:
#line 1967 "maria.y"
    { yyval.expr = NULL; ;}
    break;

  case 177:
#line 1970 "maria.y"
    {
	  yyval.expr = NULL;
	  if (yyvsp[-1].s) {
	    if (class Function* f = getFunction (yyvsp[-1].s)) {
	      if (!(yyval.expr = fold (f->expand (NULL)))) {
		thePrinter.printRaw ("could not expand nullary function ");
		thePrinter.printQuoted (f->getName ());
		thePrinter.finish ();
		pnerrors++;
	      }
	    }
	    else {
	      thePrinter.printRaw ("there is no nullary function ");
	      thePrinter.printQuoted (yyvsp[-1].s);
	      thePrinter.finish ();
	      pnerrors++;
	    }
	  }
	;}
    break;

  case 178:
#line 1991 "maria.y"
    {
	  class Function* f = NULL;
	  if (yyvsp[-1].s && !(f = getFunction (yyvsp[-1].s))) {
	    thePrinter.printRaw ("there is no function ");
	    thePrinter.printQuoted (yyvsp[-1].s);
	    thePrinter.finish ();
	    pnerrors++;
	  }
	  delete[] yyvsp[-1].s;
	  functionStack.push (f);
	;}
    break;

  case 179:
#line 2003 "maria.y"
    {
	  assert (!functionStack.empty ());
	  if (class Function* f = functionStack.top ()) {
	    yyval.expr = NULL;
	    if (yyvsp[-1].exprList && !(yyval.expr = fold (f->expand (yyvsp[-1].exprList)))) {
	      thePrinter.printRaw ("could not expand function ");
	      thePrinter.printQuoted (f->getName ());
	      thePrinter.finish ();
	      pnerrors++;
	    }
	  }
	  else
	    yyval.expr = NULL;
	  yyvsp[-1].exprList->destroy ();
	  functionStack.pop ();
	;}
    break;

  case 180:
#line 2021 "maria.y"
    {
	  yyval.expr = (new class Constant
		(*new class LeafValue (Net::getBoolType (), true)))->cse ();
	;}
    break;

  case 181:
#line 2027 "maria.y"
    {
	  yyval.expr = (new class Constant
		(*new class LeafValue (Net::getBoolType (), false)))->cse ();
	;}
    break;

  case 182:
#line 2033 "maria.y"
    { yyval.expr = yyvsp[0].place ? (new class PlaceContents (*yyvsp[0].place))->cse () : NULL; ;}
    break;

  case 183:
#line 2036 "maria.y"
    { yyval.expr = resolveName (yyvsp[0].s); ;}
    break;

  case 184:
#line 2039 "maria.y"
    {
	  yyval.expr = (new class Constant
		(*new class LeafValue (Net::getCardType (), yyvsp[0].i)))->cse ();
	;}
    break;

  case 185:
#line 2045 "maria.y"
    {
	  yyval.expr = (new class Constant
		(*new class LeafValue (Net::getCharType (), yyvsp[0].c)))->cse ();
	;}
    break;

  case 186:
#line 2051 "maria.y"
    { yyval.expr = (new class Undefined (Undefined::fError))->cse (); ;}
    break;

  case 187:
#line 2054 "maria.y"
    { yyval.expr = (new class Undefined (Undefined::fFatalError))->cse (); ;}
    break;

  case 188:
#line 2057 "maria.y"
    {
	  structLevels.push (StructLevel
			     (currentContextType, currentComponent));

	  if (!currentType) {
	    pnerror ("cannot determine type of structured expression");
	    currentContextType = NULL, currentComponent = 0;
	  }
	  else {
	    assert (!structLevels.empty () || !currentComponent);
	    currentContextType = currentType;
	    currentComponent = 0;

	    switch (currentType->getKind ()) {
	    case Type::tStruct:
	      currentType =
		static_cast<const class StructType*>(currentContextType)
		->getSize ()
		? &(*static_cast<const class StructType*>(currentContextType))
		[currentComponent]
		: NULL;
	      break;
	    case Type::tVector:
	      currentType =
		&static_cast<const class VectorType*>(currentContextType)
		->getItemType ();

	      if (pnwarnings) {
		const class Type& indexType =
		  static_cast<const class VectorType*>(currentContextType)
		  ->getIndexType ();

		switch (indexType.getKind ()) {
		case Type::tInt:
		case Type::tCard:
		case Type::tBool:
		case Type::tChar:
		case Type::tEnum:
		case Type::tId:
		  if (const class Constraint* constraint =
		      indexType.getConstraint ()) {
		    if (constraint->size () <= 1)
		      break;
		  }
		  else
		    break;
		default:
		  pnwarn ("initializing an array indexed by something else"
			  " than a simple continuous type");
		}
	      }

	      break;
	    case Type::tBuffer:
	      currentType =
		&static_cast<const class BufferType*>(currentContextType)
		->getItemType ();

	      break;
	    default:
	      pnerror ("cannot determine type of structured expression");
	      currentType = currentContextType = NULL;
	    }
	  }
	;}
    break;

  case 189:
#line 2124 "maria.y"
    {
	  yyval.expr = yyvsp[-1].expr;
	  if (currentContextType) {
	    if (yyval.expr) {
	      switch (yyval.expr->getKind ()) {
	      case Expression::eStruct:
		{
		  class StructExpression* s =
		    static_cast<class StructExpression*>(yyval.expr);
		  if (s->getNextType ()) {
		    thePrinter.printRaw ("structure ");
		    printType (*currentContextType);
		    thePrinter.printRaw (" not fully initialized");
		    thePrinter.finish ();
		    pnerrors++;
		    yyval.expr->destroy (), yyval.expr = NULL;
		  }
		}
		break;

	      case Expression::eConstant:
	      case Expression::eBuffer:
		break;

	      case Expression::eVector:
		{
		  card_t diff =
		    static_cast<const class VectorType*>(currentContextType)
		    ->getSize () - currentComponent;

		  if (diff) {
		    thePrinter.print (diff);
		    thePrinter.printRaw (diff == 1
					 ? " element of array "
					 : " elements of array ");
		    printType (*currentContextType);
		    thePrinter.printRaw (" left uninitialized");
		    thePrinter.finish ();
		    pnerrors++;

		    yyval.expr->destroy (), yyval.expr = NULL;
		  }
		}
		break;

	      default:
		assert (false);
	      }
	    }

	    StructLevel p = structLevels.top ();
	    currentType = currentContextType;
	    currentContextType = p.first;
	    currentComponent = p.second;
	  }
	  else
	    currentComponent = 0;

	  structLevels.pop ();

	  if (yyval.expr)
	    yyval.expr = fold (yyval.expr);
	;}
    break;

  case 190:
#line 2189 "maria.y"
    { pushTypeContext (yyvsp[0].type); ;}
    break;

  case 191:
#line 2191 "maria.y"
    {
	  if ((yyval.expr = yyvsp[0].expr) && yyval.expr->getKind () == Expression::eMarking &&
	      yyval.expr->getType () == currentType);
	  else if ((yyval.expr = noMarking (yyval.expr)) && currentType) {
	    if (!yyval.expr->getType ()) {
	      pnerror ("expression to cast has no type");
	      yyval.expr->destroy (), yyval.expr = NULL;
	    }
	    else
	      makeCompatible (yyval.expr, *currentType, true);
	  }
	  popTypeContext ();
	;}
    break;

  case 192:
#line 2206 "maria.y"
    {
	  StructLevel p (currentContextType, currentComponent);
	  structLevels.push (p);
	  currentContextType = currentType;
	  currentType = NULL, currentComponent = 0;

	  if (yyvsp[-1].s && currentContextType &&
	      currentContextType->getKind () == Type::tUnion) {
	    const class UnionType* u =
	      static_cast<const class UnionType*>(currentContextType);

	    if ((currentType = (*u)[yyvsp[-1].s]))
	      currentComponent = u->getIndex (yyvsp[-1].s);
	    else {
	      thePrinter.printRaw ("type ");
	      printType (*u);
	      thePrinter.printRaw (" does not have component ");
	      thePrinter.printQuoted (yyvsp[-1].s);
	      thePrinter.finish ();
	      pnerrors++;
	    }
	  }
	  else if (yyvsp[-1].s)
	    pnerror ("cannot assign the component of a non-union type");

	  delete[] yyvsp[-1].s;
	;}
    break;

  case 193:
#line 2234 "maria.y"
    {
	  if ((yyvsp[0].expr = ensureExpr (yyvsp[0].expr)) && currentType) {
	    const class UnionType* u =
	      static_cast<const class UnionType*>(currentContextType);

	    if (isCompatible (yyvsp[0].expr, currentType))
	      yyval.expr = fold (new class UnionExpression (*u, *yyvsp[0].expr,
						    currentComponent));
	    else {
	      thePrinter.printRaw ("type mismatch for ");
	      printType (*u);
	      thePrinter.printRaw (" component ");
	      thePrinter.printQuoted (u->getComponentName (currentComponent));
	      thePrinter.finish ();
	      pnerrors++;

	      yyvsp[0].expr->destroy (), yyval.expr = NULL;
	    }
	  }
	  else
	    yyvsp[0].expr->destroy (), yyval.expr = NULL;

	  assert (!structLevels.empty ());
	  StructLevel p = structLevels.top ();
	  currentType = currentContextType;
	  currentContextType = p.first;
	  currentComponent = p.second;
	  structLevels.pop ();

	  if (yyval.expr)
	    yyval.expr = fold (yyval.expr);
	;}
    break;

  case 194:
#line 2268 "maria.y"
    {
	  if ((yyvsp[-2].expr = ensureExpr (yyvsp[-2].expr)) && yyvsp[0].s) {
	    if (yyvsp[-2].expr->getType () && yyvsp[-2].expr->getType ()->getKind () == Type::tUnion) {
	      const class UnionType* u =
		static_cast<const class UnionType*>(yyvsp[-2].expr->getType ());

	      if ((*u)[yyvsp[0].s])
		yyval.expr = fold (new class UnionTypeExpression (*yyvsp[-2].expr,
							  u->getIndex (yyvsp[0].s)));
	      else {
		thePrinter.printRaw ("type ");
		printType (*u);
		thePrinter.printRaw (" does not have component ");
		thePrinter.printQuoted (yyvsp[0].s);
		thePrinter.finish ();
		pnerrors++;

		yyvsp[-2].expr->destroy (), yyval.expr = NULL;
	      }
	    }
	    else {
	      pnerror ("cannot determine the component of a non-union value");
	      yyvsp[-2].expr->destroy (), yyval.expr = NULL;
	    }
	  }
	  else
	    yyvsp[-2].expr->destroy (), yyval.expr = NULL;

	  delete[] yyvsp[0].s;

	  if (yyval.expr)
	    yyval.expr = fold (yyval.expr);
	;}
    break;

  case 195:
#line 2303 "maria.y"
    { if ((yyval.expr = noMarking (yyvsp[0].expr))) (yyval.expr = yyval.expr->cse ())->setAtomic (true); ;}
    break;

  case 196:
#line 2306 "maria.y"
    { beginAny (yyvsp[-1].type, NULL, false); ;}
    break;

  case 197:
#line 2308 "maria.y"
    { yyval.expr = endAny (yyvsp[-3].type, NULL, yyvsp[0].expr); ;}
    break;

  case 198:
#line 2311 "maria.y"
    { beginAny (yyvsp[-2].type, yyvsp[-1].s, false); ;}
    break;

  case 199:
#line 2313 "maria.y"
    { yyval.expr = endAny (yyvsp[-4].type, yyvsp[-3].s, yyvsp[0].expr); ;}
    break;

  case 200:
#line 2316 "maria.y"
    { yyval.expr = newRelopExpression (false, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 201:
#line 2319 "maria.y"
    { yyval.expr = newRelopExpression (true, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 202:
#line 2322 "maria.y"
    { yyval.expr = newRelopExpression (false, yyvsp[0].expr, yyvsp[-2].expr); ;}
    break;

  case 203:
#line 2325 "maria.y"
    { yyval.expr = newNotExpression (newRelopExpression (false, yyvsp[-2].expr, yyvsp[0].expr)); ;}
    break;

  case 204:
#line 2328 "maria.y"
    { yyval.expr = newNotExpression (newRelopExpression (true, yyvsp[-2].expr, yyvsp[0].expr)); ;}
    break;

  case 205:
#line 2331 "maria.y"
    { yyval.expr = newNotExpression (newRelopExpression (false, yyvsp[0].expr, yyvsp[-2].expr)); ;}
    break;

  case 206:
#line 2334 "maria.y"
    {
	  if (yyvsp[-2].expr && yyvsp[-2].expr->getType () &&
	      yyvsp[-2].expr->getType ()->getKind () == Type::tBuffer) {
	    const class BufferType* type =
	      static_cast<const class BufferType*>(yyvsp[-2].expr->getType ());
	    if ((yyvsp[-2].expr = ensureExpr (yyvsp[-2].expr)) && (yyvsp[0].expr = ensureExpr (yyvsp[0].expr)) &&
		isCompatible (yyvsp[0].expr, &type->getItemType ())) {
	      if (yyvsp[-2].expr->getKind () == Expression::eBufferIndex) {
		class BufferIndex* b = static_cast<class BufferIndex*>(yyvsp[-2].expr);
		yyval.expr = fold (new class BufferWrite (b->getBuffer (), *yyvsp[0].expr,
						  &b->getIndex ()));
		b->destroy ();
	      }
	      else
		yyval.expr = fold (new class BufferWrite (*yyvsp[-2].expr, *yyvsp[0].expr, NULL));
	    }
	    else
	      yyvsp[-2].expr->destroy (), yyvsp[0].expr->destroy (), yyval.expr = NULL;
	  }
	  else
	    yyval.expr = newBinopExpression (BinopExpression::bPlus, yyvsp[-2].expr, yyvsp[0].expr);
	;}
    break;

  case 207:
#line 2358 "maria.y"
    {
	  if ((yyvsp[-2].expr = ensureExpr (yyvsp[-2].expr)) && yyvsp[-2].expr->getType () &&
	      yyvsp[-2].expr->getType ()->getKind () == Type::tBuffer) {
	    if ((yyval.expr = ensureBuffer (yyvsp[-2].expr))) {
	      class Expression* i = 0;
	      if (yyval.expr->getKind () == Expression::eBufferIndex) {
		class BufferIndex* b = static_cast<class BufferIndex*>(yyval.expr);
		yyval.expr = &b->getBuffer ();
		i = &b->getIndex ();
		b->destroy ();
	      }
	      yyval.expr = fold (new class BufferRemove (*yyval.expr, ensureCard (yyvsp[0].expr), i));
	    }
	  }
	  else
	    yyval.expr = newBinopExpression (BinopExpression::bMinus, yyvsp[-2].expr, yyvsp[0].expr);
	;}
    break;

  case 208:
#line 2377 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bDiv, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 209:
#line 2380 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bMul, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 210:
#line 2383 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bMod, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 211:
#line 2386 "maria.y"
    {
	  if ((yyval.expr = ensureIntCard (yyvsp[0].expr)))
	    yyval.expr = fold (new class UnopExpression (UnopExpression::uNot, *yyval.expr));
	;}
    break;

  case 212:
#line 2392 "maria.y"
    {
	  if (yyvsp[0].type) {
	    card_t num = yyvsp[0].type->getNumValues ();
	    assert (num > 0);
	    if (num == CARD_T_MAX) {
	      pnerror ("type has too many values to count");
	      yyval.expr = NULL;
	    }
	    else
	      yyval.expr = (new class Constant (*new class LeafValue
					(Net::getCardType (), num)))->cse ();
	  }
	  else
	    yyval.expr = NULL;
	;}
    break;

  case 213:
#line 2409 "maria.y"
    {
	  if (yyvsp[0].type && isOrdered (*yyvsp[0].type))
	    yyval.expr = (new class Constant (yyvsp[0].type->getFirstValue ()))->cse ();
	  else
	    yyval.expr = NULL;
	;}
    break;

  case 214:
#line 2417 "maria.y"
    {
	  if (yyvsp[0].type && isOrdered (*yyvsp[0].type))
	    yyval.expr = (new class Constant (yyvsp[0].type->getLastValue ()))->cse ();
	  else
	    yyval.expr = NULL;
	;}
    break;

  case 215:
#line 2425 "maria.y"
    {
	  if ((yyval.expr = ensureOrdered (yyvsp[0].expr)))
	    yyval.expr = fold (new class UnopExpression (UnopExpression::uPred, *yyval.expr));
	;}
    break;

  case 216:
#line 2431 "maria.y"
    {
	  if ((yyval.expr = ensureOrdered (yyvsp[0].expr)))
	    yyval.expr = fold (new class UnopExpression (UnopExpression::uSucc, *yyval.expr));
	;}
    break;

  case 217:
#line 2437 "maria.y"
    {
	  if ((yyvsp[0].expr = ensureExpr (yyvsp[0].expr)) && yyvsp[0].expr->getType () &&
	      yyvsp[0].expr->getType ()->getKind () == Type::tBuffer) {
	    if ((yyval.expr = ensureBuffer (yyvsp[0].expr))) {
	      class Expression* i = 0;
	      if (yyval.expr->getKind () == Expression::eBufferIndex) {
		class BufferIndex* b = static_cast<class BufferIndex*>(yyval.expr);
		yyval.expr = &b->getBuffer ();
		i = &b->getIndex ();
		b->destroy ();
	      }
	      yyval.expr = fold (new class BufferRemove (*yyval.expr, 0, i));
	    }
	  }
	  else if ((yyval.expr = ensureIntCard (yyvsp[0].expr)))
	    yyval.expr = fold (new class UnopExpression (UnopExpression::uNeg, *yyval.expr));
	;}
    break;

  case 218:
#line 2456 "maria.y"
    { yyval.expr = newBufferUnop (BufferUnop::bPeek, yyvsp[0].expr); ;}
    break;

  case 219:
#line 2459 "maria.y"
    { yyval.expr = newBufferUnop (BufferUnop::bUsed, yyvsp[0].expr); ;}
    break;

  case 220:
#line 2462 "maria.y"
    { yyval.expr = newBufferUnop (BufferUnop::bFree, yyvsp[0].expr); ;}
    break;

  case 221:
#line 2465 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bRol, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 222:
#line 2468 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bRor, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 223:
#line 2471 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bAnd, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 224:
#line 2474 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bXor, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 225:
#line 2477 "maria.y"
    { yyval.expr = newBinopExpression (BinopExpression::bOr, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 226:
#line 2480 "maria.y"
    {
	  yyvsp[-2].expr = noMarking (yyvsp[-2].expr);
	  if (yyvsp[-2].expr && yyvsp[0].exprList) {
	    if (!yyvsp[-2].expr->getType ()) {
	      pnerror ("left-hand-side of ? has no type");
	      yyvsp[-2].expr->destroy (); yyvsp[0].exprList->destroy (); yyval.expr = NULL;
	    }
	    else if (yyvsp[-2].expr->getType ()->getNumValues () != yyvsp[0].exprList->size ()) {
	      thePrinter.printRaw ("left-hand-side of ? has ");
	      thePrinter.print (yyvsp[-2].expr->getType ()->getNumValues ());
	      thePrinter.printRaw ("!=");
	      thePrinter.print (yyvsp[0].exprList->size ());
	      thePrinter.printRaw (" possible values");
	      thePrinter.finish ();
	      pnerrors++;
	      yyvsp[-2].expr->destroy (); yyvsp[0].exprList->destroy (); yyval.expr = NULL;
	    }
	    else if (yyvsp[-2].expr->getType ()->getNumValues () == 1) {
	      pnwarn ("left-hand-side of ? has only one possible value");
	      yyval.expr = (*yyvsp[0].exprList)[0].copy (); yyvsp[-2].expr->destroy (); yyvsp[0].exprList->destroy ();
	    }
	    else
	      yyval.expr = fold (new class IfThenElse (*yyvsp[-2].expr, *yyvsp[0].exprList));
	  }
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].exprList->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 227:
#line 2510 "maria.y"
    {
	  if ((yyvsp[-3].expr = ensureExpr (yyvsp[-3].expr))) {
	    if (!yyvsp[-3].expr->getType () ||
		yyvsp[-3].expr->getType ()->getKind () != Type::tVector) {
	      pnerror ("left-hand-side of .{[index]expr} is not an array");
	      yyvsp[-3].expr->destroy (), yyvsp[-3].expr = NULL;
	    }
	    else
	      pushTypeContext (&static_cast<const class VectorType*>
			       (yyvsp[-3].expr->getType ())->getIndexType ());
	  }
	;}
    break;

  case 228:
#line 2523 "maria.y"
    {
	  if (yyvsp[-6].expr)
	    currentType = &static_cast<const class VectorType*>(yyvsp[-6].expr->getType ())
	      ->getItemType ();
	;}
    break;

  case 229:
#line 2529 "maria.y"
    {
	  if (yyvsp[-9].expr) {
	    currentType = yyvsp[-9].expr->getType ();
	    const class VectorType& type =
	      *static_cast<const class VectorType*>(currentType);

	    if (makeCompatible (yyvsp[-4].expr, type.getIndexType ()) &&
		makeCompatible (yyvsp[-1].expr, type.getItemType ()))
	      yyval.expr = fold (new class VectorAssign (*yyvsp[-9].expr, *yyvsp[-4].expr, *yyvsp[-1].expr));
	    else
	      yyvsp[-4].expr->destroy (), yyvsp[-1].expr->destroy (), yyvsp[-9].expr->destroy (), yyval.expr = NULL;
	    popTypeContext ();
	  }
	  else
	    yyvsp[-4].expr->destroy (), yyvsp[-1].expr->destroy (), yyval.expr = NULL;
	;}
    break;

  case 230:
#line 2547 "maria.y"
    {
	  if ((yyvsp[-3].expr = ensureExpr (yyvsp[-3].expr)) && yyvsp[0].s) {
	    if (!yyvsp[-3].expr->getType () ||
		yyvsp[-3].expr->getType ()->getKind () != Type::tStruct) {
	      pnerror ("left-hand-side of .{comp expr} is not a struct");
	      yyvsp[-3].expr->destroy (), yyvsp[-3].expr = NULL;
	    }
	    const class StructType& type =
	      *static_cast<const class StructType*>(yyvsp[-3].expr->getType ());
	    if (const class Type* ct = type[yyvsp[0].s])
	      pushTypeContext (ct);
	    else {
	      thePrinter.printRaw ("type ");
	      printType (type);
	      thePrinter.printRaw (" does not have component ");
	      thePrinter.printQuoted (yyvsp[0].s);
	      thePrinter.finish ();
	      pnerrors++;
	      yyvsp[-3].expr->destroy (), yyvsp[-3].expr = NULL;
	    }
	  }
	  else
	    yyvsp[-3].expr->destroy (), yyvsp[-3].expr = NULL;
	;}
    break;

  case 231:
#line 2572 "maria.y"
    {
	  if (yyvsp[-6].expr) {
	    const class StructType& type =
	      *static_cast<const class StructType*>(yyvsp[-6].expr->getType ());
	    currentType = type[yyvsp[-3].s];
	    if (makeCompatible (yyvsp[-1].expr, *currentType))
	      yyval.expr =
		fold (new class StructAssign (*yyvsp[-6].expr, type.getIndex (yyvsp[-3].s), *yyvsp[-1].expr));
	    else
	      yyvsp[-1].expr->destroy (), yyvsp[-6].expr->destroy (), yyval.expr = NULL;
	    popTypeContext ();
	  }
	  else
	    yyvsp[-1].expr->destroy (), yyval.expr = NULL;
	  delete[] yyvsp[-3].s;
	;}
    break;

  case 232:
#line 2590 "maria.y"
    {
	  yyvsp[-2].expr = ensureExpr (yyvsp[-2].expr);
	  if (yyvsp[-2].expr && yyvsp[0].s) {
	    if (yyvsp[-2].expr->getType () &&
		yyvsp[-2].expr->getType ()->getKind () == Type::tStruct) {
	      const class StructType *s =
		static_cast<const class StructType*>(yyvsp[-2].expr->getType ());
	      if ((*s)[yyvsp[0].s])
		yyval.expr = fold (new class StructComponent (*yyvsp[-2].expr, s->getIndex (yyvsp[0].s)));
	      else {
		thePrinter.printRaw ("type ");
		printType (*s);
		thePrinter.printRaw (" does not have component ");
		thePrinter.printQuoted (yyvsp[0].s);
		thePrinter.finish ();
		pnerrors++;

		yyvsp[-2].expr->destroy (), yyval.expr = NULL;
	      }
	    }
	    else if (yyvsp[-2].expr->getType () &&
		     yyvsp[-2].expr->getType ()->getKind () == Type::tUnion) {
	      const class UnionType *u =
		static_cast<const class UnionType*>(yyvsp[-2].expr->getType ());
	      if ((*u)[yyvsp[0].s])
		yyval.expr = fold (new class UnionComponent (*yyvsp[-2].expr, u->getIndex (yyvsp[0].s)));
	      else {
		thePrinter.printRaw ("type ");
		printType (*u);
		thePrinter.printRaw (" does not have component ");
		thePrinter.printQuoted (yyvsp[0].s);
		thePrinter.finish ();
		pnerrors++;

		yyvsp[-2].expr->destroy (), yyval.expr = NULL;
	      }
	    }
	    else {
	      pnerror ("only unions and structs have components");
	      yyvsp[-2].expr->destroy (), yyval.expr = NULL;
	    }
	  }
	  else
	    yyvsp[-2].expr->destroy (), yyval.expr = NULL;

	  delete[] yyvsp[0].s;
	;}
    break;

  case 233:
#line 2639 "maria.y"
    {
	  if ((yyvsp[-1].expr = ensureExpr (yyvsp[-1].expr)) && yyvsp[-1].expr->getType ()) {
	    switch (yyvsp[-1].expr->getType ()->getKind ()) {
	    case Type::tVector:
	      {
		const class VectorType* type =
		  static_cast<const class VectorType*>(yyvsp[-1].expr->getType ());
		pushTypeContext (&type->getIndexType ());
	      }
	      break;
	    case Type::tBuffer:
	      if (yyvsp[-1].expr->getKind () == Expression::eBufferIndex)
		pnerror ("a buffer index has already been specified");
	      break;
	    default:
	      pnerror ("only vector-typed expressions can be indexed");
	      yyvsp[-1].expr->destroy (), yyvsp[-1].expr = NULL;
	    }
	  }
	  else if (yyvsp[-1].expr) {
	    pnerror ("no type for indexed expression");
	    yyvsp[-1].expr->destroy (), yyvsp[-1].expr = NULL;
	  }
	;}
    break;

  case 234:
#line 2664 "maria.y"
    {
	  if (yyvsp[-4].expr) {
	    switch (yyvsp[-4].expr->getType ()->getKind ()) {
	    case Type::tVector:
	      {
		const class VectorType* type =
		  static_cast<const class VectorType*>(yyvsp[-4].expr->getType ());
		popTypeContext ();

		if (isCompatible (yyvsp[-1].expr, &type->getIndexType ()))
		  yyval.expr = fold (new class VectorIndex (*yyvsp[-4].expr, *yyvsp[-1].expr));
		else
		  yyval.expr = NULL, yyvsp[-4].expr->destroy (), yyvsp[-1].expr->destroy ();
	      }
	      break;
	    case Type::tBuffer:
	      yyvsp[-1].expr = ensureCard (yyvsp[-1].expr);
	      if (yyvsp[-4].expr->getKind () == Expression::eBufferIndex)
		yyvsp[-1].expr->destroy (), yyval.expr = yyvsp[-4].expr;
	      else
		yyval.expr = yyvsp[-1].expr ? (new class BufferIndex (*yyvsp[-4].expr, *yyvsp[-1].expr))->cse () : yyvsp[-4].expr;
	      break;
	    default:
	      assert (false);
	    }
	  }
	  else
	    yyval.expr = NULL, yyvsp[-1].expr->destroy ();
	;}
    break;

  case 235:
#line 2695 "maria.y"
    { yyval.expr = newNotExpression (yyvsp[0].expr); ;}
    break;

  case 236:
#line 2698 "maria.y"
    {
	  yyvsp[-2].expr = ensureBool (yyvsp[-2].expr); yyvsp[0].expr = ensureBool (yyvsp[0].expr, true);
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = newBooleanBinop (true, yyvsp[-2].expr, yyvsp[0].expr);
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 237:
#line 2708 "maria.y"
    {
	  yyvsp[-2].expr = ensureBool (yyvsp[-2].expr); yyvsp[0].expr = ensureBool (yyvsp[0].expr, true);
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = newBooleanBinop (false, yyvsp[-2].expr, yyvsp[0].expr);
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 238:
#line 2718 "maria.y"
    {
	  yyvsp[-2].expr = ensureBool (yyvsp[-2].expr); yyvsp[0].expr = ensureBool (yyvsp[0].expr, true);
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = newBooleanBinop (false, newNotExpression (yyvsp[-2].expr), yyvsp[0].expr);
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 239:
#line 2728 "maria.y"
    {
	  yyval.expr = newNotExpression
	    (newRelopExpression (true, ensureBool (yyvsp[-2].expr), ensureBool (yyvsp[0].expr)));
	;}
    break;

  case 240:
#line 2734 "maria.y"
    { yyval.expr = newRelopExpression (true, ensureBool (yyvsp[-2].expr), ensureBool (yyvsp[0].expr)); ;}
    break;

  case 241:
#line 2737 "maria.y"
    {
	  yyvsp[0].expr = ensureBool (yyvsp[0].expr);
	  yyval.expr = yyvsp[0].expr
	    ? (new class TemporalUnop (TemporalUnop::Finally, *yyvsp[0].expr))->cse ()
	    : NULL;
	;}
    break;

  case 242:
#line 2745 "maria.y"
    {
	  yyvsp[0].expr = ensureBool (yyvsp[0].expr);
	  yyval.expr = yyvsp[0].expr
	    ? (new class TemporalUnop (TemporalUnop::Globally, *yyvsp[0].expr))->cse ()
	    : NULL;
	;}
    break;

  case 243:
#line 2753 "maria.y"
    {
	  yyvsp[0].expr = ensureBool (yyvsp[0].expr);
	  yyval.expr = yyvsp[0].expr
	    ? (new class TemporalUnop (TemporalUnop::Next, *yyvsp[0].expr))->cse ()
	    : NULL;
	;}
    break;

  case 244:
#line 2761 "maria.y"
    {
	  yyvsp[-2].expr = ensureBool (yyvsp[-2].expr); yyvsp[0].expr = ensureBool (yyvsp[0].expr);
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = (new class TemporalBinop
		  (TemporalBinop::Until, *yyvsp[-2].expr, *yyvsp[0].expr))->cse ();
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 245:
#line 2772 "maria.y"
    {
	  yyvsp[-2].expr = ensureBool (yyvsp[-2].expr); yyvsp[0].expr = ensureBool (yyvsp[0].expr);
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = (new class TemporalBinop
		  (TemporalBinop::Release, *yyvsp[-2].expr, *yyvsp[0].expr))->cse ();
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 246:
#line 2783 "maria.y"
    { yyval.expr = (new class EmptySet)->cse (); ;}
    break;

  case 247:
#line 2786 "maria.y"
    { yyval.expr = newSetExpression (SetExpression::sSubset, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 248:
#line 2789 "maria.y"
    { yyval.expr = newSetExpression (SetExpression::sIntersection, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 249:
#line 2792 "maria.y"
    { yyval.expr = newSetExpression (SetExpression::sMinus, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 250:
#line 2795 "maria.y"
    { yyval.expr = newSetExpression (SetExpression::sUnion, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 251:
#line 2798 "maria.y"
    { yyval.expr = newSetExpression (SetExpression::sEquals, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;

  case 252:
#line 2801 "maria.y"
    { yyval.expr = newCardinalityExpression (CardinalityExpression::cCard, yyvsp[0].expr); ;}
    break;

  case 253:
#line 2804 "maria.y"
    { yyval.expr = newCardinalityExpression (CardinalityExpression::cMin, yyvsp[0].expr); ;}
    break;

  case 254:
#line 2807 "maria.y"
    { yyval.expr = newCardinalityExpression (CardinalityExpression::cMax, yyvsp[0].expr); ;}
    break;

  case 255:
#line 2810 "maria.y"
    { yyval.expr = yyvsp[-1].expr; ;}
    break;

  case 256:
#line 2813 "maria.y"
    {
	  yyvsp[-2].expr = ensureCard (yyvsp[-2].expr);
	  class Marking* m = ensureMarking (yyvsp[0].expr, currentType);

	  if ((yyval.expr = m) && yyvsp[-2].expr) {
	    if (yyvsp[-2].expr->getKind () == Expression::eConstant) {
	      const class Value& v =
		static_cast<class Constant*>(yyvsp[-2].expr)->getValue ();
	      assert (v.getKind () == Value::vLeaf);
	      card_t mult = card_t (static_cast<const class LeafValue&>(v));
	      if (!mult) {
		pnerror ("zero multiplicity");
		yyvsp[-2].expr->destroy (), m->destroy ();
		yyval.expr = m = NULL;
	      }
	      else if (mult == 1)
		yyvsp[-2].expr->destroy ();
	      else {
		for (;;) {
		  if (class Expression* c = m->getMultiplicity ()) {
		    class Expression* card =
		      fold (new class BinopExpression (BinopExpression::bMul,
						       *yyvsp[-2].expr, *c));
		    m->setMultiplicity (card);
		  }
		  else
		    m->setMultiplicity (yyvsp[-2].expr);

		  if ((m = const_cast<class Marking*>(m->getNext ())))
		    yyvsp[-2].expr = (new class Constant
			  (*new class LeafValue
			   (*yyvsp[-2].expr->getType (), mult)))->cse ();
		  else
		    break;
		}
	      }
	    }
	    else {
	      if (m->getNext ())
		yyval.expr = m = static_cast<class Marking*>
		  ((new class Marking (m->getPlace (), m))->cse ());

	      class Expression* card = yyvsp[-2].expr;

	      if (class Expression* c = m->getMultiplicity ())
		card = fold
		  (new class BinopExpression (BinopExpression::bMul, *yyvsp[-2].expr, *c));
	      m->setMultiplicity (card);
	    }
	  }
	  else
	    yyvsp[-2].expr->destroy ();
	;}
    break;

  case 257:
#line 2868 "maria.y"
    { beginQuantifier (yyvsp[0].s, yyvsp[-1].type); ;}
    break;

  case 258:
#line 2870 "maria.y"
    { continueQuantifier (ASSERT1 (yyvsp[-3].type)); ;}
    break;

  case 259:
#line 2872 "maria.y"
    { yyval.expr = endQuantifier (yyvsp[-5].s, yyvsp[-6].type, yyvsp[-3].expr, yyvsp[-1].i, yyvsp[0].expr, false); ;}
    break;

  case 260:
#line 2875 "maria.y"
    { yyval.expr = quantifierVariable (yyvsp[-1].s, yyvsp[0].s, false); ;}
    break;

  case 261:
#line 2878 "maria.y"
    { yyval.expr = quantifierVariable (yyvsp[-1].s, yyvsp[0].s, true); ;}
    break;

  case 262:
#line 2881 "maria.y"
    {
	  if (yyvsp[-1].expr && yyvsp[-1].expr->getKind () == Expression::eEmptySet) {
	    pnwarn ("any subset of an empty set is an empty set");
	    delete[] yyvsp[-3].s, yyvsp[-3].s = NULL;
	  }
	  else if ((yyvsp[-1].expr = ensureSet (yyvsp[-1].expr)) && yyvsp[-3].s && yyvsp[-1].expr->getType ()) {
	    checkIterator (yyvsp[-3].s);
	    currentVariables.push (new class VariableDefinition
				   (yyvsp[-3].s, *yyvsp[-1].expr->getType (), false));
	  }
	  else
	    delete[] yyvsp[-3].s, yyvsp[-3].s = NULL;
	;}
    break;

  case 263:
#line 2895 "maria.y"
    {
	  yyvsp[0].expr = ensureBool (ensureExpr (yyvsp[0].expr));
	  if ((yyval.expr = yyvsp[-3].expr) && yyvsp[0].expr && yyvsp[-5].s) {
	    yyvsp[0].expr = yyvsp[0].expr->cse ();
	    if (pnwarnings) {
	      class VariableSet vars;
	      vars.insert (*currentVariables.top ());
	      if (!yyvsp[0].expr->depends (vars, false)) {
		thePrinter.printRaw ("Warning:subset is independent of ");
		thePrinter.printQuoted (currentVariables.top ()->getName ());
		thePrinter.finish ();
	      }
	    }
	    if (yyvsp[0].expr->getKind () == Expression::eConstant) {
	      const class Value& v =
		static_cast<class Constant*>(yyvsp[0].expr)->getValue ();
	      assert (v.getKind () == Value::vLeaf);
	      bool result = bool (static_cast<const class LeafValue&>(v));
	      yyvsp[0].expr->destroy ();
	      pnwarn (result
		      ? "subset criterion always passes"
		      : "subset criterion always fails");
	      if (!result)
		yyval.expr->destroy (), yyval.expr = (new class EmptySet)->cse ();
	    }
	    else
	      yyval.expr = (new class Submarking
		    (*currentVariables.top (), *yyvsp[-3].expr, *yyvsp[0].expr))->cse ();
	  }
	  else
	    yyvsp[0].expr->destroy ();
	  if (yyvsp[-5].s)
	    currentVariables.pop ();
	;}
    break;

  case 264:
#line 2931 "maria.y"
    {
	  if (yyvsp[-1].expr && yyvsp[-1].expr->getKind () == Expression::eEmptySet) {
	    pnwarn ("any subset of an empty set is an empty set");
	    delete[] yyvsp[-3].s, yyvsp[-3].s = NULL;
	  }
	  else if ((yyvsp[-1].expr = ensureSet (yyvsp[-1].expr)) && yyvsp[-3].s && yyvsp[-1].expr->getType ()) {
	    checkIterator (yyvsp[-3].s);
	    currentVariables.push (new class VariableDefinition
				   (yyvsp[-3].s, *yyvsp[-1].expr->getType (), false));
	  }
	  else
	    delete[] yyvsp[-3].s, yyvsp[-3].s = NULL;
	;}
    break;

  case 265:
#line 2945 "maria.y"
    {
	  yyvsp[0].expr = ensureExpr (yyvsp[0].expr);
	  if ((yyval.expr = yyvsp[-3].expr) && yyvsp[-5].s && yyvsp[0].expr) {
	    yyvsp[0].expr = yyvsp[0].expr->cse ();
	    if (pnwarnings) {
	      class VariableSet vars;
	      vars.insert (*currentVariables.top ());
	      if (!yyvsp[0].expr->depends (vars, false)) {
		thePrinter.printRaw ("Warning:mapping is independent of ");
		thePrinter.printQuoted (currentVariables.top ()->getName ());
		thePrinter.finish ();
	      }
	      else if (yyvsp[0].expr->getKind () == Expression::eVariable &&
		       &static_cast<class Variable*>(yyvsp[0].expr)->getVariable () ==
		       currentVariables.top ()) {
		thePrinter.printRaw ("Warning:mapping has no effect");
		thePrinter.finish ();
	      }
	    }

	    if (yyvsp[0].expr->getKind () == Expression::eVariable &&
		&static_cast<class Variable*>(yyvsp[0].expr)->getVariable () ==
		currentVariables.top ()) {
	      currentVariables.pop ();
	      delete &static_cast<class Variable*>(yyvsp[0].expr)->getVariable ();
	      yyvsp[-5].s = 0;
	      yyvsp[0].expr->destroy ();
	      yyval.expr = yyvsp[-3].expr;
	    }
	    else
	      yyval.expr = (new class Mapping
		    (*currentVariables.top (), NULL, *yyvsp[-3].expr, *yyvsp[0].expr))->cse ();
	  }
	  else
	    yyvsp[0].expr->destroy ();
	  if (yyvsp[-5].s)
	    currentVariables.pop ();
	;}
    break;

  case 266:
#line 2985 "maria.y"
    {
	  if (yyvsp[-1].expr && yyvsp[-1].expr->getKind () == Expression::eEmptySet) {
	    pnwarn ("any subset of an empty set is an empty set");
	    delete[] yyvsp[-5].s, yyvsp[-5].s = NULL;
	    delete[] yyvsp[-3].s, yyvsp[-3].s = NULL;
	  }
	  else if ((yyvsp[-1].expr = ensureSet (yyvsp[-1].expr)) && yyvsp[-5].s && yyvsp[-3].s && yyvsp[-1].expr->getType ()) {
	    checkIterator (yyvsp[-5].s); checkIterator (yyvsp[-3].s);
	    currentVariables.push (new class VariableDefinition
				   (yyvsp[-5].s, Net::getCardType (), false));
	    currentVariables.push (new class VariableDefinition
				   (yyvsp[-3].s, *yyvsp[-1].expr->getType (), false));
	  }
	  else {
	    delete[] yyvsp[-5].s, yyvsp[-5].s = NULL;
	    delete[] yyvsp[-3].s, yyvsp[-3].s = NULL;
	  }
	;}
    break;

  case 267:
#line 3004 "maria.y"
    {
	  yyvsp[0].expr = yyvsp[0].expr ? ensureMarking (yyvsp[0].expr, yyvsp[0].expr->getType ()) : 0;
	  yyval.expr = yyvsp[-3].expr;
	  if (yyvsp[-7].s && yyvsp[-5].s) {
	    class VariableDefinition* token = currentVariables.top ();
	    currentVariables.pop ();
	    class VariableDefinition* mult = currentVariables.top ();
	    currentVariables.pop ();
	    if (yyval.expr && yyvsp[0].expr) {
	      yyvsp[0].expr = yyvsp[0].expr->cse ();
	      if (pnwarnings) {
		class VariableSet vars;
		vars.insert (*token);
		vars.insert (*mult);
		if (!yyvsp[0].expr->depends (vars, false)) {
		  thePrinter.printRaw ("Warning:mapping depends neither on ");
		  thePrinter.printQuoted (token->getName ());
		  thePrinter.printRaw (" nor ");
		  thePrinter.printQuoted (mult->getName ());
		  thePrinter.finish ();
		}
	      }
	      yyval.expr = (new class Mapping
		    (*token, mult, *yyvsp[-3].expr, *yyvsp[0].expr))->cse ();
	    }
	    else
	      yyvsp[0].expr->destroy ();
	  }
	  else
	    yyvsp[0].expr->destroy ();
	;}
    break;

  case 268:
#line 3038 "maria.y"
    {
	  if (class Function* f = functionStack.top ()) {
	    if (!f->getArity ())
	      yyval.exprList = new class ExpressionList;
	    else {
	      thePrinter.printRaw ("function ");
	      thePrinter.printQuoted (f->getName ());
	      thePrinter.printRaw (" expects ");
	      thePrinter.print (f->getArity ());
	      thePrinter.printRaw (", not zero arguments");
	      thePrinter.finish ();
	      pnerrors++;
	      yyval.exprList = NULL;
	    }
	  }
	  else
	    yyval.exprList = NULL;
	;}
    break;

  case 269:
#line 3057 "maria.y"
    {
	  const class Type* type = NULL;

	  if (class Function* f = functionStack.top ()) {
	    if (f->getArity ())
	      type = &(*f)[0].getType ();
	    else {
	      thePrinter.printRaw ("function ");
	      thePrinter.printQuoted (f->getName ());
	      thePrinter.printRaw (" takes no arguments");
	      thePrinter.finish ();
	      pnerrors++;
	    }
	  }

	  pushTypeContext (type);
	;}
    break;

  case 270:
#line 3075 "maria.y"
    {
	  if (currentType &&
	      isCompatible ((yyvsp[0].expr = noMarking (yyvsp[0].expr)), currentType)) {
	    if (functionStack.top ())
	      (yyval.exprList = new class ExpressionList)->append (*yyvsp[0].expr);
	    else {
	      yyvsp[0].expr->destroy (); yyval.exprList = NULL;
	    }
	  }
	  else {
	    yyvsp[0].expr->destroy (); yyval.exprList = NULL;
	  }
	  popTypeContext ();
	;}
    break;

  case 271:
#line 3091 "maria.y"
    {
	  const class Type* type = NULL;

	  if (class Function* f = functionStack.top ()) {
	    if (yyvsp[-1].exprList) {
	      if (f->getArity () > yyvsp[-1].exprList->size ())
		type = &(*f)[yyvsp[-1].exprList->size ()].getType ();
	      else {
		thePrinter.printRaw ("function ");
		thePrinter.printQuoted (f->getName ());
		thePrinter.printRaw (" takes only ");
		thePrinter.print (f->getArity ());
		thePrinter.printRaw (" arguments");
		thePrinter.finish ();
		pnerrors++;
	      }
	    }
	  }

	  pushTypeContext (type);
	;}
    break;

  case 272:
#line 3113 "maria.y"
    {
	  if ((yyval.exprList = yyvsp[-3].exprList) && currentType &&
	      isCompatible ((yyvsp[0].expr = noMarking (yyvsp[0].expr)), currentType)) {
	    if (functionStack.top ())
	      yyval.exprList->append (*yyvsp[0].expr);
	    else {
	      yyval.exprList->destroy (); yyvsp[0].expr->destroy (); yyval.exprList = NULL;
	    }
	  }
	  else {
	    yyval.exprList->destroy (); yyvsp[0].expr->destroy (); yyval.exprList = NULL;
	  }
	  popTypeContext ();
	;}
    break;

  case 273:
#line 3129 "maria.y"
    { if ((yyval.exprList = yyvsp[-1].exprList)) pnerror ("extraneous comma in argument list"); ;}
    break;

  case 274:
#line 3135 "maria.y"
    {
	  if (yyvsp[0].expr)
	    (yyval.exprList = new class ExpressionList)->prepend (*yyvsp[0].expr);
	  else
	    yyval.exprList = NULL;
	;}
    break;

  case 275:
#line 3143 "maria.y"
    {
	  if ((yyval.exprList = yyvsp[-2].exprList) && yyvsp[0].expr) {
	    if (yyval.exprList->getType () && yyvsp[0].expr->getType () &&
		yyval.exprList->getType () != yyvsp[0].expr->getType ()) {
	      pnerror ("incompatible types in ?: expression");
	      yyval.exprList->destroy (), yyvsp[0].expr->destroy (), yyval.exprList = NULL;
	    }
	    else if ((yyvsp[0].expr = yyval.exprList->isSet ()
		      ? ensureMarking (yyvsp[0].expr, yyval.exprList->getType ()
				       ? yyval.exprList->getType ()
				       : yyvsp[0].expr->getType ())
		      : noMarking (yyvsp[0].expr)))
	      yyval.exprList->prepend (*yyvsp[0].expr);
	    else
	      yyval.exprList->destroy (), yyvsp[0].expr->destroy (), yyval.exprList = NULL;
	  }
	  else
	    yyval.exprList->destroy (), yyvsp[0].expr->destroy (), yyval.exprList = NULL;
	;}
    break;

  case 276:
#line 3166 "maria.y"
    { beginQuantifier (yyvsp[0].s, yyvsp[-1].type); ;}
    break;

  case 277:
#line 3168 "maria.y"
    { continueQuantifier (ASSERT1 (yyvsp[-3].type)); ;}
    break;

  case 278:
#line 3170 "maria.y"
    { yyval.expr = endQuantifier (yyvsp[-5].s, yyvsp[-6].type, yyvsp[-3].expr, yyvsp[-1].i, yyvsp[0].expr, true); ;}
    break;

  case 279:
#line 3173 "maria.y"
    { currentContextTransition = yyvsp[-1].trans; ;}
    break;

  case 280:
#line 3175 "maria.y"
    {
	  yyvsp[0].expr = ensureBool (ensureExpr (yyvsp[0].expr));
	  if (yyvsp[-3].trans && yyvsp[0].expr)
	    yyval.expr = (new class TransitionQualifier (*yyvsp[-3].trans, *yyvsp[0].expr->cse ()))->cse ();
	  else
	    yyvsp[0].expr->destroy (), yyval.expr = NULL;
	  currentContextTransition = NULL;
	;}
    break;

  case 281:
#line 3185 "maria.y"
    {
	  yyval.expr = yyvsp[0].trans
	    ? (new class TransitionQualifier
	       (*yyvsp[0].trans, *(new class Constant
		       (*new class LeafValue
			(Net::getBoolType (), true)))->cse ()))->cse ()
	    : NULL;
	;}
    break;

  case 282:
#line 3195 "maria.y"
    { yyval.expr = yyvsp[-1].expr; ;}
    break;

  case 283:
#line 3198 "maria.y"
    { yyval.expr = newNotExpression (yyvsp[0].expr); ;}
    break;

  case 284:
#line 3201 "maria.y"
    {
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = newBooleanBinop (true, yyvsp[-2].expr, yyvsp[0].expr);
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 285:
#line 3210 "maria.y"
    {
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = newBooleanBinop (false, yyvsp[-2].expr, yyvsp[0].expr);
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 286:
#line 3219 "maria.y"
    {
	  if (yyvsp[-2].expr && yyvsp[0].expr)
	    yyval.expr = newBooleanBinop (false, newNotExpression (yyvsp[-2].expr), yyvsp[0].expr);
	  else {
	    yyvsp[-2].expr->destroy (); yyvsp[0].expr->destroy (); yyval.expr = NULL;
	  }
	;}
    break;

  case 287:
#line 3228 "maria.y"
    { yyval.expr = newNotExpression (newRelopExpression (true, yyvsp[-2].expr, yyvsp[0].expr)); ;}
    break;

  case 288:
#line 3231 "maria.y"
    { yyval.expr = newRelopExpression (true, yyvsp[-2].expr, yyvsp[0].expr); ;}
    break;


    }

/* Line 1010 of yacc.c.  */
#line 5361 "maria.tab.c"

  yyvsp -= yylen;
  yyssp -= yylen;


  YY_STACK_PRINT (yyss, yyssp);

  *++yyvsp = yyval;


  /* Now `shift' the result of the reduction.  Determine what state
     that goes to, based on the state we popped back to and the rule
     number reduced by.  */

  yyn = yyr1[yyn];

  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
    yystate = yytable[yystate];
  else
    yystate = yydefgoto[yyn - YYNTOKENS];

  goto yynewstate;


/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
  /* If not already recovering from an error, report this error.  */
  if (!yyerrstatus)
    {
      ++yynerrs;
#if YYERROR_VERBOSE
      yyn = yypact[yystate];

      if (YYPACT_NINF < yyn && yyn < YYLAST)
	{
	  YYSIZE_T yysize = 0;
	  int yytype = YYTRANSLATE (yychar);
	  const char* yyprefix;
	  char *yymsg;
	  int yyx;

	  /* Start YYX at -YYN if negative to avoid negative indexes in
	     YYCHECK.  */
	  int yyxbegin = yyn < 0 ? -yyn : 0;

	  /* Stay within bounds of both yycheck and yytname.  */
	  int yychecklim = YYLAST - yyn;
	  int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
	  int yycount = 0;

	  yyprefix = ", expecting ";
	  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
	    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
	      {
		yysize += yystrlen (yyprefix) + yystrlen (yytname [yyx]);
		yycount += 1;
		if (yycount == 5)
		  {
		    yysize = 0;
		    break;
		  }
	      }
	  yysize += (sizeof ("syntax error, unexpected ")
		     + yystrlen (yytname[yytype]));
	  yymsg = (char *) YYSTACK_ALLOC (yysize);
	  if (yymsg != 0)
	    {
	      char *yyp = yystpcpy (yymsg, "syntax error, unexpected ");
	      yyp = yystpcpy (yyp, yytname[yytype]);

	      if (yycount < 5)
		{
		  yyprefix = ", expecting ";
		  for (yyx = yyxbegin; yyx < yyxend; ++yyx)
		    if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
		      {
			yyp = yystpcpy (yyp, yyprefix);
			yyp = yystpcpy (yyp, yytname[yyx]);
			yyprefix = " or ";
		      }
		}
	      yyerror (yymsg);
	      YYSTACK_FREE (yymsg);
	    }
	  else
	    yyerror ("syntax error; also virtual memory exhausted");
	}
      else
#endif /* YYERROR_VERBOSE */
	yyerror ("syntax error");
    }



  if (yyerrstatus == 3)
    {
      /* If just tried and failed to reuse lookahead token after an
	 error, discard it.  */

      if (yychar <= YYEOF)
        {
          /* If at end of input, pop the error token,
	     then the rest of the stack, then return failure.  */
	  if (yychar == YYEOF)
	     for (;;)
	       {
		 YYPOPSTACK;
		 if (yyssp == yyss)
		   YYABORT;
		 YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
		 yydestruct (yystos[*yyssp], yyvsp);
	       }
        }
      else
	{
	  YYDSYMPRINTF ("Error: discarding", yytoken, &yylval, &yylloc);
	  yydestruct (yytoken, &yylval);
	  yychar = YYEMPTY;

	}
    }

  /* Else will try to reuse lookahead token after shifting the error
     token.  */
  goto yyerrlab1;


/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR.  |
`---------------------------------------------------*/
yyerrorlab:

#ifdef __GNUC__
  /* Pacify GCC when the user code never invokes YYERROR and the label
     yyerrorlab therefore never appears in user code.  */
  if (0)
     goto yyerrorlab;
#endif

  yyvsp -= yylen;
  yyssp -= yylen;
  yystate = *yyssp;
  goto yyerrlab1;


/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR.  |
`-------------------------------------------------------------*/
yyerrlab1:
  yyerrstatus = 3;	/* Each real token shifted decrements this.  */

  for (;;)
    {
      yyn = yypact[yystate];
      if (yyn != YYPACT_NINF)
	{
	  yyn += YYTERROR;
	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
	    {
	      yyn = yytable[yyn];
	      if (0 < yyn)
		break;
	    }
	}

      /* Pop the current state because it cannot handle the error token.  */
      if (yyssp == yyss)
	YYABORT;

      YYDSYMPRINTF ("Error: popping", yystos[*yyssp], yyvsp, yylsp);
      yydestruct (yystos[yystate], yyvsp);
      YYPOPSTACK;
      yystate = *yyssp;
      YY_STACK_PRINT (yyss, yyssp);
    }

  if (yyn == YYFINAL)
    YYACCEPT;

  YYDPRINTF ((stderr, "Shifting error token, "));

  *++yyvsp = yylval;


  yystate = yyn;
  goto yynewstate;


/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here.  |
`-------------------------------------*/
yyacceptlab:
  yyresult = 0;
  goto yyreturn;

/*-----------------------------------.
| yyabortlab -- YYABORT comes here.  |
`-----------------------------------*/
yyabortlab:
  yyresult = 1;
  goto yyreturn;

#ifndef yyoverflow
/*----------------------------------------------.
| yyoverflowlab -- parser overflow comes here.  |
`----------------------------------------------*/
yyoverflowlab:
  yyerror ("parser stack overflow");
  yyresult = 2;
  /* Fall through.  */
#endif

yyreturn:
#ifndef yyoverflow
  if (yyss != yyssa)
    YYSTACK_FREE (yyss);
#endif
  return yyresult;
}


#line 3234 "maria.y"


static void
checkIterator (const char* name)
{
  checkName (name, ckIter, "invalid iterator variable name ");
}

static class Type*
copyType (class Type* type)
{
  if (type->getName () || Net::isPredefinedType (*type)) {
    if (!theNet.hasType (*type)) theNet.addType (*type, 0);
    return type->copy ();
  }
  else
    return type;
}

static void
deleteType (class Type* type)
{
  if (type && !type->getName () && !Net::isPredefinedType (*type) &&
      !theNet.hasType (*type))
    delete type;
}

static void
printType (const class Type& type)
{
  if (const char* name = type.getName ())
    thePrinter.print (name);
  else
    type.display (thePrinter);
}

static void pushTypeContext (const class Type* type)
{
  StructLevel p (currentContextType, currentComponent);
  structLevels.push (p);
  StructLevel q (currentType, 0);
  structLevels.push (q);

  currentType = type;
  currentContextType = NULL, currentComponent = 0;
}

static void popTypeContext ()
{
  StructLevel p = structLevels.top ();
  structLevels.pop ();
  currentType = p.first;
  assert (!p.second);
  p = structLevels.top ();
  structLevels.pop ();
  currentContextType = p.first;
  currentComponent = p.second;
}

static const class VariableDefinition*
getParameter (char* name)
{
  for (unsigned i = 0; i < currentArity; i++) {
    if (!strcmp (currentParameters[i]->getName (), name))
      return currentParameters[i];
  }

  return NULL;
}

static void
addParameter (const class Type* type, char* name)
{
  if (!type || !name) {
    delete[] name;
    return;
  }

  if (getParameter (name)) {
    thePrinter.printRaw ("ignoring redefinition of parameter ");
    thePrinter.printQuoted (name);
    thePrinter.finish ();
    pnerrors++;
    delete[] name;
    return;
  }

  checkName (name, ckParam, "invalid function parameter name ");

  if (pnwarnings) {
    const char* shadow = 0;
    if (currentTransition && currentTransition->getVariable (name))
      shadow = " shadows a variable";
    else if (getConstant (name) || getConstantFunction (name))
      shadow = " shadows a constant";
    else if (getType (name))
      shadow = " shadows a type name";

    if (shadow) {
      thePrinter.printRaw ("Warning:parameter ");
      thePrinter.printQuoted (name);
      thePrinter.printRaw (shadow);
      thePrinter.finish ();
    }
  }

  class VariableDefinition** v =
    new class VariableDefinition*[currentArity + 1];
  assert (!currentArity || currentParameters);
  assert (currentArity || !currentParameters);

  memcpy (v, currentParameters, currentArity * sizeof *v);
  delete[] currentParameters;
  currentParameters = v;
  currentParameters[currentArity++] =
    new class VariableDefinition (name, *type, false);
}

static const class Type*
getType (const char* name)
{
  for (const class Net* n = net; n; n = n->getParent ())
    if (const class Type* type = n->getType (name))
      return type;
  return 0;
}

static class Function*
getFunction (const char* name)
{
  class Function* f = currentTransition
    ? currentTransition->getFunction (name)
    : (currentContextTransition
       ? currentContextTransition->getFunction (name)
       : NULL);
  if (!f)
    for (class Net* n = net; n; n = const_cast<class Net*>(n->getParent ()))
      if ((f = n->getFunction (name)))
	break;
  return f;
}

static class Function*
getConstantFunction (const char* name)
{
  class Function* f = currentTransition
    ? currentTransition->getFunction (name)
    : (currentContextTransition
       ? currentContextTransition->getFunction (name)
       : NULL);
  if (!f || f->getArity ())
    for (class Net* n = net; n; n = const_cast<class Net*>(n->getParent ()))
      if ((f = n->getFunction (name)) && !f->getArity ())
	break;
  return f && f->getArity () ? NULL : f;
}

static const class Constant*
getConstant (const char* name)
{
  const class Constant* c = currentTransition
    ? currentTransition->getConstant (name)
    : (currentContextTransition
       ? currentContextTransition->getConstant (name)
       : NULL);
  if (!c)
    for (const class Net* n = net; n; n = n->getParent ())
      if ((c = n->getConstant (name)))
	break;
  return c;
}

static const class Expression*
getProposition (char* name)
{
  for (const class Net* n = net; n; n = n->getParent ())
    for (unsigned i = n->getNumProps (); i--; )
      if (!strcmp (n->getPropName (i), name))
	return &n->getProp (i);
  return 0;
}

static const class VariableDefinition*
getVariable (char* name)
{
  assert (name != NULL);

  const class VariableDefinition* v = getParameter (name);
  const class Function* f = getConstantFunction (name);
  const class Constant* c = getConstant (name);

  if (v || (v = currentVariables.find (name)))
    goto found;

  if (!currentTransition) {
    if (currentContextTransition &&
	(v = currentContextTransition->getVariable (name)));
    else if (!f && !c &&
	     !(currentType && currentType->getKind () == Type::tEnum &&
	       static_cast<const class EnumType*>(currentType)
	       ->getValue (name)) &&
	     !getProposition (name)) {
      thePrinter.printRaw ("undefined variable ");
      thePrinter.printQuoted (name);
      thePrinter.finish ();
      pnerrors++;
    }
    delete[] name;
  }
  else if ((v = currentTransition->getVariable (name))) {
  found:
    delete[] name;
  }
  else if (f || c)
    delete[] name;
  else if (!currentType) {
    thePrinter.printRaw ("cannot determine the type of variable ");
    thePrinter.printQuoted (name);
    thePrinter.finish ();
    pnerrors++;
    delete[] name;
  }
  else {
    assert (currentType != NULL);

    if (pnwarnings && getType (name)) {
      thePrinter.printRaw ("Warning:variable ");
      thePrinter.printQuoted (name);
      thePrinter.printRaw (" shadows a type name");
      thePrinter.finish ();
    }

    if (currentType->getKind () != Type::tEnum ||
	!static_cast<const class EnumType*>(currentType)->getValue (name)) {
      checkName (name, ckVar, "invalid (implicit) variable name ");
      v = &currentTransition->addVariable (name, *currentType, false, false);
    }
    else
      delete[] name;
  }

  return v;
}

static class Expression*
resolveName (char* name)
{
  const class Constant* c = getConstant (name);
  class Function* f = getConstantFunction (name);
  const card_t*const i =
    (currentType && currentType->getKind () == Type::tEnum)
    ? static_cast<const class EnumType*>(currentType)->getValue (name)
    : NULL;
  const class Expression* prop = getProposition (name);

  if (const class VariableDefinition* d = getVariable (name))
    return static_cast<class Variable*>((new class Variable (*d))->cse ());
  else if (c)
    return (const_cast<class Constant*>(c)->copy ())->cse ();
  else if (class Expression* expr = f ? f->expand (NULL) : NULL)
    return fold (expr);
  else if (i)
    return enumValue (*static_cast<const class EnumType*>(currentType), *i);
  else if (prop)
    return (const_cast<class Expression*>(prop)->copy ())->cse ();
  else
    return NULL;
}

static class Expression*
ensureSet (class Expression* expr,
	   const class Type* type)
{
  return !expr || expr->isSet () ? expr : ensureMarking (expr, type);
}

static class Marking*
ensureMarking (class Expression* expr,
	       const class Type* type,
	       bool temporal)
{
  if (!expr)
    return NULL;
  else if (expr->getKind () == Expression::eUndefined) {
    pnerror ("undefined marking expressions are not allowed");
    expr->destroy ();
    return NULL;
  }

  assert (expr->getType () || expr->getKind () == Expression::eEmptySet);

  if (expr->getKind () == Expression::eMarking)
    return static_cast<class Marking*>(expr);
  else if (expr->isSet () || expr->isBasic ()) {
    if (currentPlace) {
      if (!type)
	type = &currentPlace->getType ();
      if (!makeCompatible (expr, *type)) {
	pnerror ("marking expression has incompatible type");
	return NULL;
      }
    }

    if (!type || makeCompatible (expr, *type)) {
      class Marking* m = new class Marking (type ? 0 : currentPlace);
      m->setToken (expr);
      return m;
    }
    else
      return NULL;
  }
  else if (temporal) {
    class Marking* m = new class Marking (currentPlace);
    m->setToken (expr);
    return m;
  }
  else {
    pnerror ("marking expression expected");
    expr->destroy ();
    return NULL;
  }
}

static class Expression*
noMarking (class Expression* expr)
{
  if (expr && expr->isSet ()) {
    pnerror ("marking expression not allowed here");
    expr->destroy ();
    return NULL;
  }

  return expr;
}

static class Expression*
ensureExpr (class Expression* expr)
{
  expr = noMarking (expr);

  if (expr && !expr->isBasic ()) {
    pnerror ("basic expression expected");
    expr->destroy (); return NULL;
  }

  return expr;
}

static class Expression*
ensureBool (class Expression* expr, bool undefined)
{
  expr = noMarking (expr);

  if (!expr)
    return NULL;

  if (expr->getKind () == Expression::eUndefined) {
    if (undefined)
      return expr;
    pnerror ("undefined or fatal expression is not meaningful here");
    expr->destroy (); return NULL;
  }

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    expr->destroy (); return NULL;
  }

  if (expr->getType ()->getKind () != Type::tBool) {
    pnerror ("boolean expression expected");
    expr->destroy (); return NULL;
  }

  return expr;
}

static class Expression*
ensureInt (class Expression* expr)
{
  expr = ensureExpr (expr);

  if (!expr)
    return NULL;

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    expr->destroy (); return NULL;
  }

  switch (expr->getType ()->getKind ()) {
  case Type::tInt:
    return expr;
  case Type::tEnum:
  case Type::tChar:
  case Type::tCard:
  case Type::tBool:
    if (!makeCompatible (expr, Net::getIntType (), true));
    else if (expr->getType () == &Net::getIntType ())
      return expr;
    /* fall through */
  default:
    pnerror ("signed integer expression expected");
    expr->destroy ();
    return NULL;
  }
}

static class Expression*
ensureCard (class Expression* expr)
{
  expr = ensureExpr (expr);

  if (!expr)
    return NULL;

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    expr->destroy (); return NULL;
  }

  switch (expr->getType ()->getKind ()) {
  case Type::tCard:
    return expr;
  case Type::tEnum:
  case Type::tChar:
  case Type::tInt:
  case Type::tBool:
    if (!makeCompatible (expr, Net::getCardType (), true));
    else if (expr->getType () == &Net::getCardType ())
      return expr;
    /* fall through */
  default:
    pnerror ("unsigned integer expression expected");
    expr->destroy ();
    return NULL;
  }
}

static class Expression*
ensureIntCard (class Expression* expr)
{
  expr = ensureExpr (expr);

  if (!expr)
    return NULL;

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    expr->destroy (); return NULL;
  }

  switch (expr->getType ()->getKind ()) {
  case Type::tCard:
  case Type::tInt:
    return expr;
  case Type::tEnum:
  case Type::tChar:
  case Type::tBool:
    if (!makeCompatible (expr, Net::getCardType (), true));
    else if (expr->getType () == &Net::getCardType () ||
	     expr->getType () == &Net::getIntType ())
      return expr;
    /* fall through */
  default:
    pnerror ("integer expression expected");
    expr->destroy ();
    return NULL;
  }
}

static class Expression*
ensureBuffer (class Expression* expr)
{
  expr = ensureExpr (expr);

  if (!expr)
    return NULL;

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    expr->destroy (); return NULL;
  }

  if (expr->getType ()->getKind () != Type::tBuffer) {
    pnerror ("buffer expression expected");
    expr->destroy (); return NULL;
  }

  return expr;
}

static class Expression*
ensureOrdered (class Expression* expr)
{
  expr = ensureExpr (expr);

  if (!expr)
    return NULL;

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    expr->destroy (); return NULL;
  }

  if (!isOrdered (*expr->getType ())) {
    expr->destroy (); return NULL;
  }

  return expr;
}

static void
addEnumeration (class EnumType* e, char* name)
{
  assert (e && name);
  const card_t* const i = e->getValue (name);
  if (i) {
    thePrinter.printRaw ("enumeration constant ");
    thePrinter.printQuoted (name);
    thePrinter.printRaw (" already defined as ");
    thePrinter.print (*i);
    thePrinter.finish ();
    pnerrors++;
    delete[] name;
  }
  else
    e->addEnumeration (name);
  if (pnwarnings) {
    if (getConstant (name)) {
      thePrinter.printRaw ("Warning:enumeration constant ");
      thePrinter.printQuoted (name);
      thePrinter.printRaw (" shadows a constant");
      thePrinter.finish ();
    }
    else if (getType (name)) {
      thePrinter.printRaw ("Warning:enumeration constant ");
      thePrinter.printQuoted (name);
      thePrinter.printRaw (" shadows a type name");
      thePrinter.finish ();
    }
  }
}

static void
addEnumeration (class EnumType* e, char* name, card_t value)
{
  assert (e && name);
  const card_t* const i = e->getValue (name);
  if (e->getValue (name)) {
    thePrinter.printRaw ("enumeration constant ");
    thePrinter.printQuoted (name);
    thePrinter.printRaw (" already defined as ");
    thePrinter.print (*i);
    thePrinter.finish ();
    pnerrors++;
    delete[] name;
  }
  else if (e->hasValue (value)) {
    thePrinter.printRaw ("enumeration already contains the value ");
    thePrinter.print (value);
    thePrinter.finish ();
    pnerrors++;
    delete[] name;
  }
  else
    e->addEnumeration (name, value);
  if (pnwarnings) {
    if (getConstant (name)) {
      thePrinter.printRaw ("Warning:enumeration constant ");
      thePrinter.printQuoted (name);
      thePrinter.printRaw (" shadows a constant");
      thePrinter.finish ();
    }
    else if (getType (name)) {
      thePrinter.printRaw ("Warning:enumeration constant ");
      thePrinter.printQuoted (name);
      thePrinter.printRaw (" shadows a type name");
      thePrinter.finish ();
    }
  }
}

static class Value*
ensureConstant (class Expression* expr, const class Type* type)
{
  if (!(expr = fold (expr)))
    return NULL;

  if (!type) {
    expr->destroy ();
    return NULL;
  }

  if (!isOrdered (*type)) {
    expr->destroy ();
    return NULL;
  }

  class Value* v = NULL;
  if (expr->getKind () == Expression::eConstant) {
    const class Valuation empty;
    v = expr->eval (empty);
    assert (!!v);
  }
  else
    pnerror ("constant expected");

  expr->destroy ();

  switch (type->getKind ()) {
  case Type::tInt:
  case Type::tCard:
  case Type::tBool:
  case Type::tChar:
  case Type::tEnum:
    break;
  default:
    if (&v->getType () == type)
      return v;
    thePrinter.printRaw ("unable to convert constant from ");
    printType (v->getType ());
    thePrinter.printRaw (" to ");
    printType (*type);
    thePrinter.finish ();
    pnerrors++;
    delete v;
    return NULL;
  }

  /** the integer value */
  struct {
    /** tag: is the value unsigned */
    bool u;
    /** the actual value */
    union {
      int_t i; ///< signed
      card_t u; ///< unsigned
    } v;
  } value;

  switch (v->getType ().getKind ()) {
  case Type::tInt:
    assert (v->getKind () == Value::vLeaf);
    if (&v->getType () == type)
      return v;
    value.u = false, value.v.i = int_t (static_cast<class LeafValue&>(*v));
    break;
  case Type::tCard:
    assert (v->getKind () == Value::vLeaf);
    if (&v->getType () == type)
      return v;
    value.u = true, value.v.u = card_t (static_cast<class LeafValue&>(*v));
    break;
  case Type::tBool:
    assert (v->getKind () == Value::vLeaf);
    if (&v->getType () == type)
      return v;
    value.u = true, value.v.u = bool (static_cast<class LeafValue&>(*v));
    break;
  case Type::tChar:
    assert (v->getKind () == Value::vLeaf);
    if (&v->getType () == type)
      return v;
    value.u = false, value.v.i = int_t (static_cast<class LeafValue&>(*v));
    break;
  case Type::tEnum:
    assert (v->getKind () == Value::vLeaf);
    if (&v->getType () == type)
      return v;
    value.u = true, value.v.u = card_t (static_cast<class LeafValue&>(*v));
    break;

  default:
    if (&v->getType () == type)
      return v;
    thePrinter.printRaw ("cannot define constraint: incompatible type ");
    printType (v->getType ());
    thePrinter.finish ();
    pnerrors++;
    delete v;
    return NULL;
  }

  if (pnwarnings && v->getType ().getKind () != type->getKind () &&
      !((type->getKind () == Type::tInt || type->getKind () == Type::tCard) &&
	(v->getType ().getKind () == Type::tInt ||
	 v->getType ().getKind () == Type::tCard))) {
    thePrinter.printRaw ("Warning:converting constant ");
    thePrinter.print (value.u ? value.v.u : value.v.i);
    thePrinter.printRaw (" from ");
    printType (v->getType ());
    thePrinter.printRaw (" to ");
    printType (*type);
    thePrinter.finish ();
  }

  delete v;
  v = NULL;
  switch (type->getKind ()) {
  case Type::tInt:
    if (value.u) {
      if (value.v.u > INT_T_MAX)
	break;
      value.v.i = value.v.u, value.u = false;
    }
    if (type->isConstrained (*(v = new class LeafValue (*type, value.v.i))))
      return v;
    delete v;
    break;
  case Type::tCard:
    if (!value.u) {
      if (value.v.i < 0)
	break;
      value.v.u = value.v.i, value.u = true;
    }
    if (type->isConstrained (*(v = new class LeafValue (*type, value.v.u))))
      return v;
    delete v;
    break;
  case Type::tBool:
    if (value.u) {
      if ((value.v.u == 0 || value.v.u == 1) &&
	  type->isConstrained (*(v = new class LeafValue (*type,
							  value.v.u == 1))))
	return v;
    }
    else {
      if ((value.v.i == 0 || value.v.i == 1) &&
	  type->isConstrained (*(v = new class LeafValue (*type,
							  value.v.i == 1))))
	return v;
    }
    delete v;
    break;
  case Type::tChar:
    if (!value.u) {
      if (value.v.i < 0)
	break;
      value.v.u = value.v.i, value.u = true;
    }
    if (value.v.u <= CHAR_T_MAX &&
	type->isConstrained (*(v = new class LeafValue (*type, value.v.u))))
      return v;
    delete v;
    break;
  case Type::tEnum:
    if (!value.u) {
      if (value.v.i < 0)
	break;
      value.v.u = value.v.i, value.u = true;
    }
    if (type->isConstrained (*(v = new class LeafValue (*type, value.v.u))) ||
	!type->getConstraint ())
      return v;
    delete v;
    break;

  default:
    assert (false);
  }

  thePrinter.printRaw ("value ");
  thePrinter.print (value.u ? value.v.u : value.v.i);
  thePrinter.printRaw (" out of range for type ");
  printType (*type);
  thePrinter.finish ();
  pnerrors++;
  return NULL;
}

static class Expression*
enumValue (const class EnumType& type, card_t value)
{
  class LeafValue* e = new class LeafValue (type, value);
  if (type.isConstrained (*e))
    return (new class Constant (*e))->cse ();
  else {
    thePrinter.printRaw ("enumeration constant ");
    if (const char* c = type.getEnumName (value)) {
      thePrinter.print (c);
      thePrinter.delimiter ('=');
    }
    thePrinter.print (value);
    thePrinter.printRaw (" out of range for type ");
    printType (type);
    thePrinter.finish ();
    pnerrors++;
    delete e;
    return NULL;
  }
}

static class Expression*
namedComponent (char* name, class Expression* expr)
{
  if (!name) {
    expr->destroy ();
    return NULL;
  }

  if (!currentContextType || currentContextType->getKind () != Type::tStruct) {
    thePrinter.printRaw ("named component ");
    thePrinter.printQuoted (name);
    thePrinter.printRaw (" can only be used with a struct");
    thePrinter.finish ();
    pnerrors++;
    expr->destroy ();
    delete[] name;
    return NULL;
  }

  const class StructType& type =
    static_cast<const class StructType&>(*currentContextType);

  if (currentComponent < type.getSize ()) {
    const char* comp = type.getComponentName (currentComponent);
    if (strcmp (name, comp)) {
      thePrinter.printRaw ("expecting named component ");
      thePrinter.printQuoted (comp);
      thePrinter.printRaw (" instead of ");
      thePrinter.printQuoted (name);
      thePrinter.finish ();
      pnerrors++;
      expr->destroy ();
      delete[] name;
      return NULL;
    }
  }
  else {
    thePrinter.printRaw ("extraneous named component ");
    thePrinter.printQuoted (name);
    thePrinter.printRaw (" at end of struct");
    thePrinter.finish ();
    pnerrors++;
    expr->destroy ();
    delete[] name;
    return NULL;
  }

  delete[] name;
  return expr;
}

static void
beginAny (class Type*& type, char* name,
	  bool hidden)
{
  if (type) {
    if (currentTransition) {
      if (currentTransition->getKind ()) {
	thePrinter.printRaw ("assertion transitions do not output");
	thePrinter.finish ();
	pnerrors++;
	type = NULL; delete[] name;
      }
      else if (name && currentTransition->getVariable (name)) {
	thePrinter.printRaw ("output variable ");
	thePrinter.printQuoted (name);
	thePrinter.printRaw (" shadows another variable");
	thePrinter.finish ();
	pnerrors++;
	type = NULL; delete[] name;
      }
      else {
	if (name) {
	  checkIterator (name);
	  currentTransition->addVariable (name, *type, true, hidden);
	}
	card_t size = type->getNumValues ();
	if (!size || size == CARD_T_MAX || (maxRange && size > maxRange)) {
	  thePrinter.printRaw ("type ");
	  printType (*type);
	  thePrinter.printRaw (" has too many (");
	  thePrinter.print (size);
	  thePrinter.printRaw (") values for non-determinism");
	  if (size && size < CARD_T_MAX)
	    thePrinter.printRaw (" (try -q0)");
	  thePrinter.finish ();
	  pnerrors++;
	}
      }
    }
    else {
      pnerror ("non-determinism is only allowed on output arcs");
      type = NULL; delete[] name;
    }
  }
  else
    delete[] name;

  pushTypeContext (type);
}

static class Variable*
endAny (const class Type* type,
	char* name,
	class Expression* condition)
{
  class Variable* var;
  popTypeContext ();

  if (type) {
    if (!condition || (condition = ensureBool (ensureExpr (condition)))) {
      var = static_cast<class Variable*>
	((new class Variable
	  (currentTransition->addOutputVariable (*type, name,
						 condition)))->cse ());
      assert (var != NULL);
      if (pnwarnings && condition) {
	class VariableSet vars;
	vars.insert (var->getVariable ());
	if (!condition->depends (vars, false)) {
	  thePrinter.printRaw ("Warning:condition is independent of ");
	  thePrinter.printQuoted (var->getVariable ().getName ());
	  thePrinter.finish ();
        }
      }
    }
    else
      var = NULL, condition->destroy ();
  }
  else
    var = NULL, condition->destroy ();
  return var;
}

static void
beginQuantifier (char* name, const class Type* type)
{
  if (name && type) {
    checkIterator (name);
    if (pnwarnings) {
      const char* shadow = 0;
      if (currentVariables.find (name))
        shadow = " shadows another quantifier";
      else if ((currentTransition &&
		currentTransition->getVariable (name)) ||
	       (currentContextTransition &&
		currentContextTransition->getVariable (name)))
	shadow = " shadows a transition variable";
      else if (getConstant (name))
	shadow = " shadows a constant";
      else if (currentType && currentType->getKind () == Type::tEnum &&
	       static_cast<const class EnumType*>(currentType)->
	       getValue (name))
	shadow = " shadows an enumeration constant";
      else if (getType (name))
	shadow = " shadows a type name";

      if (shadow) {
	thePrinter.printRaw ("quantifier ");
	thePrinter.printQuoted (name);
	thePrinter.printRaw (shadow);
	thePrinter.finish ();
      }
    }

    card_t size = type->getNumValues ();
    if (!size || size == CARD_T_MAX || (maxRange && size > maxRange)) {
      thePrinter.printRaw ("type ");
      printType (*type);
      thePrinter.printRaw (" has too many (");
      thePrinter.print (size);
      thePrinter.printRaw (") values for quantification");
      if (size && size < CARD_T_MAX)
	thePrinter.printRaw (" (try -q0)");
      thePrinter.finish ();
      pnerrors++;
    }
    currentVariables.push (new class VariableDefinition (name, *type, true));
  }

  struct TypeContext tc = {
    currentContextType,
    currentType,
    currentComponent
  };
  typeStack.push (tc);

  currentContextType = NULL;
  currentComponent = 0;
  currentType = type;
}

static void
continueQuantifier (ASSERT1 (const class Type* type))
{
  assert (!currentContextType);
  assert (currentType == type);
  assert (!typeStack.empty ());
  struct TypeContext tc = typeStack.top ();
  typeStack.pop ();

  currentContextType = tc.context;
  currentType = tc.component;
  currentComponent = tc.numComponent;
}

static class Expression*
endQuantifier (char* name,
	       const class Type* type,
	       class Expression* condition,
	       unsigned kind,
	       class Expression* expr,
	       bool temporal)
{
  if (name && type && expr && kind) {
    class VariableDefinition* var = currentVariables.top ();
    currentVariables.pop ();

    card_t size = var->getType ().getNumValues ();
    if (!size || size == CARD_T_MAX || (maxRange && size > maxRange)) {
      condition->destroy ();
      expr->destroy ();
      delete var;
      return NULL;
    }

    if ((condition = ensureBool (ensureExpr (condition))) && pnwarnings) {
      class VariableSet vars;
      vars.insert (*var);
      if (!condition->depends (vars, false)) {
	thePrinter.printRaw ("Warning:condition is independent of ");
	thePrinter.printQuoted (var->getName ());
	thePrinter.finish ();
      }
    }

    class Valuation v;
    switch (kind) {
    case 1:
      if (class Marking* m = ensureMarking (expr, currentType, temporal)) {
	expr = m->quantify (v,
			    currentTransition
			    ? currentTransition
			    : currentContextTransition,
			    *var, condition,
			    currentTransition && !temporal);
	m->destroy ();
	condition->destroy ();
	delete var;
	if (!expr) {
	  if (check (v))
	    pnerror ("conflicting variables in quantification");
	}
	else
	  assert (v.isOK ());
	return expr->cse ();
      }
      else
	expr = NULL;
      break;
    case 2:
    case 3:
      if ((expr = ensureBool (expr))) {
	class Expression* e =
	  BooleanBinop::quantify (kind != 2,
				  *expr, v,
				  currentTransition
				  ? currentTransition
				  : currentContextTransition,
				  *var, condition,
				  currentTransition && !temporal);
	expr->destroy ();
	delete var;
	if (!e) {
	  if (check (v))
	    pnerror ("conflicting variables in quantification");
	}
	else
	  assert (v.isOK ());
	return e->cse ();
      }
      break;
    default:
      assert (false);
    }

    expr->destroy ();
    delete var;
    return NULL;
  }
  else {
    condition->destroy (), expr->destroy ();
    if (name && type) {
      class VariableDefinition* var = currentVariables.top ();
      currentVariables.pop ();
      delete var;
    }
    else
      delete[] name;
    return NULL;
  }
}

static class Expression*
quantifierVariable (char* prefix, char* quant, bool p)
{
  char delimiter = p ? ',' : '.';
  if (!prefix) {
    delete[] prefix;
    delete[] quant;
    return NULL;
  }
  class VariableDefinition* var;
  if (currentVariables.empty ())
    var = NULL;
  else if (quant)
    var = currentVariables.find (quant);
  else
    var = currentVariables.top ();

  if (!var) {
    thePrinter.delimiter (delimiter);
    thePrinter.print (prefix);
    if (quant) {
      thePrinter.printRaw (": quantifier ");
      thePrinter.print (quant);
      thePrinter.printRaw (" not found");
    }
    else
      thePrinter.printRaw (": no quantifier found");
    thePrinter.finish ();
    pnerrors++;
  }
  else if (!var->isAggregate ()) {
    thePrinter.delimiter (delimiter);
    thePrinter.print (prefix);
    thePrinter.printRaw (": variable ");
    thePrinter.print (var->getName ());
    thePrinter.printRaw (" is not a quantifier");
    thePrinter.finish ();
    pnerrors++;
  }
  else if (!currentTransition && !currentContextTransition) {
    thePrinter.printRaw ("quantifier ");
    thePrinter.print (var->getName ());
    thePrinter.printRaw (": cannot define ");
    thePrinter.delimiter (delimiter);
    thePrinter.print (prefix);
    thePrinter.printRaw (" outside transition");
    thePrinter.finish ();
    pnerrors++;
  }
  else if (!currentType) {
    if (const class VariableDefinition* qvar = var->findChild (prefix)) {
      delete[] quant;
      delete[] prefix;
      return (new class Variable (*qvar, p))->cse ();
    }
    else {
      thePrinter.printRaw ("quantifier ");
      thePrinter.print (var->getName ());
      thePrinter.printRaw (": cannot determine the type of ");
      thePrinter.delimiter (delimiter);
      thePrinter.print (prefix);
      thePrinter.finish ();
      pnerrors++;
    }
  }
  else if (const class VariableDefinition* qvar =
	   var->addChild (prefix, *currentType)) {
    delete[] quant;
    return (new class Variable (*qvar, p))->cse ();
  }
  else {
    thePrinter.printRaw ("quantifier ");
    thePrinter.print (var->getName ());
    thePrinter.printRaw (": contradictory type for ");
    thePrinter.delimiter (delimiter);
    thePrinter.print (prefix);
    thePrinter.finish ();
    pnerrors++;
  }

  delete[] prefix;
  delete[] quant;
  return NULL;
}

static bool
makeCompatible (class Expression*& expr,
		const class Type& type,
		bool casting)
{
  if (!expr) return false;
  if (expr->getType () == &type ||
      expr->getKind () == Expression::eEmptySet)
    return true;
  assert (!!expr->getType ());
  const class Type& srcType = *expr->getType ();
  if (((Typecast::isCastable (type) &&
	Typecast::isCastable (srcType)) ||
       Type::isCompatible (srcType, type)) &&
      expr->isBasic () && !expr->isSet ()) {
    bool isConstant = expr->getKind () == Expression::eConstant;
    expr = (new class Typecast (type, *expr))->cse ();
    if (!casting && pnwarnings &&
	((!srcType.isAssignable (type) &&
	  srcType.getKind () != Type::tCard &&
	  srcType.getKind () != Type::tInt &&
	  type.getKind () != Type::tCard &&
	  type.getKind () != Type::tInt) ||
	 (!isConstant && !srcType.isAlwaysAssignable (type)))) {
      thePrinter.printRaw ("Warning:implicit conversion from ");
      printType (srcType);
      thePrinter.printRaw (" to ");
      printType (type);
      thePrinter.finish ();
    }
    if (isConstant && !(expr = fold (expr))) {
      thePrinter.printRaw ("cannot convert constant from ");
      printType (srcType);
      thePrinter.printRaw (" to ");
      printType (type);
      thePrinter.finish ();
      pnerrors++;
      return false;
    }
    return true;
  }
  else {
    thePrinter.printRaw ("cannot convert from ");
    printType (srcType);
    thePrinter.printRaw (" to ");
    printType (type);
    thePrinter.finish ();
    pnerrors++;
    return false;
  }
}

static bool
isCompatible (class Expression*& expr,
	      const class Type* type)
{
  if (!type) {
    pnerror ("too many components for struct");
    return false;
  }

  if (!expr)
    return false;

  if (!expr->getType ()) {
    pnerror ("expression has no type");
    return false;
  }

  return makeCompatible (expr, *type);
}

static bool
isCompatible (class Expression*& expr,
	      const class StructExpression& s)
{
  const class Type* type = s.getNextType ();
  const char* structName = s.getType ()->getName ();

  if (!type) {
    if (structName) {
      thePrinter.printRaw ("too many components for struct ");
      thePrinter.printQuoted (structName);
    }
    else
      thePrinter.printRaw ("too many components for struct");
    thePrinter.finish ();
    pnerrors++;
    return false;
  }

  const char* comp =
    static_cast<const class StructType*>(s.getType ())
    ->getComponentName (s.size ());

  if (!expr) {
    if (structName) {
      thePrinter.printRaw ("error in expression for struct ");
      thePrinter.printQuoted (structName);
      thePrinter.printRaw (" component ");
    }
    else
      thePrinter.printRaw ("error in expression for struct component ");
    thePrinter.printQuoted (comp);
    thePrinter.finish ();
    pnerrors++;
    return false;
  }

  if (!expr->getType ()) {
    if (structName) {
      thePrinter.printRaw ("expression for struct ");
      thePrinter.printQuoted (structName);
      thePrinter.printRaw (" component ");
    }
    else
      thePrinter.printRaw ("expression for struct component ");
    thePrinter.printQuoted (comp);
    thePrinter.printRaw (" has no type");
    thePrinter.finish ();
    pnerrors++;
    return false;
  }

  if (!makeCompatible (expr, *type))
    return false;

  if (!expr->getType ()->isAlwaysAssignable (*type)) {
    if (Type::isCompatible (*expr->getType (), *type))
      thePrinter.printRaw ("too broad type for struct ");
    else
      thePrinter.printRaw ("type mismatch for struct ");
    if (structName) {
      thePrinter.printQuoted (structName);
      thePrinter.printRaw (" component ");
    }
    else
      thePrinter.printRaw ("component ");
    thePrinter.printQuoted (comp);
    thePrinter.finish ();
    pnerrors++;
    return false;
  }
  else if (expr->getType () != type)
    expr = (new class Typecast (*type, *expr))->cse ();

  return true;
}

static bool
isOrdered (const class Type& type)
{
  if (!type.isOrdered ()) {
    thePrinter.printRaw ("unordered type ");
    printType (type);
    thePrinter.finish ();
    pnerrors++;
    return false;
  }

  return true;
}

static bool
check (const class Valuation& v)
{
  bool ok = true;

  switch (v.getError ()) {
  case errDiv0:
    ok = false, pnerror ("division by zero"); break;
  case errOver:
    ok = false, pnerror ("overflow"); break;
  case errMod:
    ok = false, pnerror ("modulus error"); break;
  case errShift:
    ok = false, pnerror ("shift error"); break;
  case errConst:
    ok = false, pnerror ("constraint violation"); break;
  case errUnion:
    ok = false, pnerror ("union violation"); break;
  case errBuf:
    ok = false, pnerror ("buffer violation"); break;
  case errCard:
    ok = false, pnerror ("cardinality overflow"); break;
  case errComp:
    assert (false);
  case errNone:
  case errVar:
  case errUndef:
  case errFatal:
    break;
  }

  return ok;
}

static class Expression*
fold (class Expression* expr)
{
  if (expr && expr->isBasic () &&
      expr->getKind () != Expression::eConstant) {
    class Valuation v;
    if (class Value* value = expr->eval (v)) {
      assert (v.isOK ());
      expr->destroy ();
      return (new class Constant (*value))->cse ();
    }
    else {
      if (!check (v)) {
	expr->destroy ();
	return NULL;
      }
      else {
	if (v.getError () == errFatal) {
	  expr->destroy ();
	  return (new class Undefined (Undefined::fFatalError))->cse ();
	}
	if (v.getError () == errUndef) {
	  expr->destroy ();
	  return (new class Undefined (Undefined::fError))->cse ();
	}

	assert (v.getError () == errVar);
	return expr->cse ();
      }
    }
  }
  else
    return expr->cse ();
}

static void
defun (const class Type* type,
       char* name,
       class Expression* expr)
{
  currentType = NULL;
  if (!currentArity && type && !type->isLeaf () && name && expr &&
      expr->getKind () == Expression::eConstant) {
    if (isCompatible (expr, type)) {
      if (currentTransition) {
	if (!currentTransition->addConstant
	    (name, *static_cast<class Constant*>(expr))) {
	redef:
	  thePrinter.printRaw ("ignoring redefinition of constant ");
	  thePrinter.printQuoted (name);
	  thePrinter.finish ();
	  pnerrors++;
	  delete[] name, expr->destroy ();
	}
	else if (pnwarnings && theNet.getConstant (name)) {
	  thePrinter.printRaw ("Warning:definition of constant ");
	  thePrinter.printQuoted (name);
	  thePrinter.printRaw (" shadows the global definition");
	  thePrinter.finish ();
	}
      }
      else if (!theNet.addConstant
	       (name, *static_cast<class Constant*>(expr)))
	goto redef;
    }
  }
  else if (type && name && expr) {
    if ((currentTransition && currentTransition->getFunction (name)) ||
	(!currentTransition && theNet.getFunction (name))) {
      thePrinter.printRaw ("ignoring redefinition of function ");
      thePrinter.printQuoted (name);
      thePrinter.finish ();
      pnerrors++;
      delete[] name, expr->destroy ();
    }
    else if (isCompatible (expr, type)) {
      class Function* f =
	new class Function (name, currentArity, currentParameters, expr);
      if (currentTransition) {
	currentTransition->addFunction (*f);
	if (pnwarnings && theNet.getFunction (name)) {
	  thePrinter.printRaw ("Warning:definition of function ");
	  thePrinter.printQuoted (name);
	  thePrinter.printRaw (" shadows the global definition");
	  thePrinter.finish ();
	}
      }
      else
	theNet.addFunction (*f);

      if (pnwarnings && getType (name)) {
	thePrinter.printRaw ("Warning:function ");
	thePrinter.printQuoted (name);
	thePrinter.printRaw (" shadows a type name");
	thePrinter.finish ();
	for (unsigned i = 0; i < currentArity; i++) {
	  class VariableSet vars;
	  vars.insert (*currentParameters[i]);
	  if (!expr->depends (vars, false)) {
	    thePrinter.printRaw ("Warning:function ");
	    thePrinter.printQuoted (name);
	    thePrinter.printRaw (" does not use parameter ");
	    thePrinter.printQuoted (currentParameters[i]->getName ());
	    thePrinter.finish ();
	  }
	}
      }
    }
    else
      delete[] name, expr->destroy ();
  }
  else
    delete[] name, expr->destroy ();
  currentArity = 0, currentParameters = 0;
  emptyParsed = false;
}

static class Expression*
newRelopExpression (bool equal,
		    class Expression* left,
		    class Expression* right)
{
  left = ensureExpr (left); right = ensureExpr (right);
  if (!left || !right);
  else if (left->getType () != right->getType ()) {
    if (left->getKind () == Expression::eConstant &&
	makeCompatible (left, *right->getType ()))
      goto ok;
    if (right->getKind () == Expression::eConstant &&
	makeCompatible (right, *left->getType ()))
      goto ok;
    pnerror ("expressions in comparison have different types");
  }
  else if (!left->getType ()->isOrdered () && !equal)
    pnerror ("cannot compare expressions of unordered type");
  else {
  ok:
    return fold (RelopExpression::construct (equal, *left, *right));
  }

  left->destroy ();
  right->destroy ();
  return 0;
}

static class Expression*
newBinopExpression (enum BinopExpression::Op op,
		    class Expression* left,
		    class Expression* right)
{
  if (left && left->getType () &&
      left->getType ()->getKind () == Type::tVector) {
    bool shl = false;
    switch (op) {
    case BinopExpression::bRol:
      shl = true;
      break;
    case BinopExpression::bRor:
      shl = false;
      break;
    default:
      ensureIntCard (left)->destroy ();
      ensureIntCard (right)->destroy ();
      return NULL;
    }
    if ((left = ensureExpr (left)) && (right = ensureCard (right))) {
      size_t size =
	static_cast<const class VectorType*>(left->getType ())->getSize ();

      if (shl ||
	  (right = fold (new class BinopExpression
			  (BinopExpression::bMinus,
			   *new class Constant (*new class LeafValue
						(Net::getCardType (),
						 card_t (size))), *right)))) {
	if (right->getKind () == Expression::eConstant) {
	  const class Value& v =
	    static_cast<class Constant*>(right)->getValue ();
	  assert (v.getKind () == Value::vLeaf);
	  card_t amount = static_cast<const class LeafValue&>(v);
	  if (!(amount %= size)) {
	    right->destroy ();
	    return left;
	  }
	}
	return fold (new class VectorShift (*left, *right));
      }
    }
    left->destroy (), right->destroy ();
    return NULL;
  }

  left = ensureIntCard (left);
  right = ensureIntCard (right);
  if (!left || !right) {
    left->destroy (), right->destroy ();
    return NULL;
  }

  if (!(right = left->getType ()->getKind () == Type::tCard
	? ensureCard (right) : ensureInt (right))) {
    left->destroy ();
    return NULL;
  }

  return fold (new class BinopExpression (op, *left, *right));
}

static class Expression*
newNotExpression (class Expression* expr)
{
  if ((expr = ensureBool (expr)))
    expr = fold (NotExpression::construct (*expr));
  return expr;
}

static class Expression*
newBooleanBinop (bool conj,
		 class Expression* left,
		 class Expression* right)
{
  assert (left && right);
  assert (left->getKind () == Expression::eUndefined ||
	  (left->getType () && left->getType ()->getKind () == Type::tBool));
  assert (right->getKind () == Expression::eUndefined ||
	  (right->getType () && right->getType ()->getKind () == Type::tBool));
  assert (left == left->cse ());
  assert (right == right->cse ());

  return (BooleanBinop::construct (conj, *left, *right))->cse ();
}

static class Expression*
newSetExpression (enum SetExpression::Op op,
		  class Expression* left,
		  class Expression* right)
{
  const class Type* type = 0;
  if (right && right->isSet ())
    type = right->getType ();
  else if (left && left->isSet ())
    type = left->getType ();
  left = ensureSet (left, type);
  right = ensureSet (right, type);
  if (!left || !right);
  else if (left->getType () == right->getType () ||
	   left->getKind () == Expression::eEmptySet ||
	   right->getKind () == Expression::eEmptySet)
    return SetExpression::construct (op, *left, *right);
  else
    pnerror ("expressions have incompatible types");
  left->destroy (), right->destroy ();
  return NULL;
}

static class Expression*
newCardinalityExpression (enum CardinalityExpression::Op op,
			  class Expression* expr)
{
  if (class Expression* m = ensureSet (expr)) {
    if (m->getKind () == Expression::eEmptySet) {
      m->destroy ();
      pnwarn ("the cardinality of an empty set is always zero");
      return (new class Constant (*new class LeafValue
				  (Net::getCardType (),
				   op == CardinalityExpression::cMin
				   ? CARD_T_MAX
				   : 0)))->cse ();
    }
    else
      return (new class CardinalityExpression (op, *m))->cse ();
  }
  else
    return NULL;
}

static class Expression*
newBufferUnop (enum BufferUnop::Op op, class Expression* expr)
{
  if (!(expr = ensureBuffer (expr)))
    return NULL;

  if (expr->getKind () == Expression::eBufferIndex) {
    class BufferIndex* b = static_cast<class BufferIndex*>(expr);
    class Expression* buffer = &b->getBuffer ();
    class Expression* i = &b->getIndex ();
    b->destroy ();
    switch (op) {
    case BufferUnop::bFree:
    case BufferUnop::bUsed:
      if (i) {
	pnwarn ("ignoring meaningless buffer indexing expression");
	i->destroy (), i = NULL;
      }
      break;
    case BufferUnop::bPeek:
      break;
    }

    return fold (new class BufferUnop (op, *buffer, i));
  }

  return fold (new class BufferUnop (op, *expr, NULL));
}

