/**
  @file 

  @ingroup nanotrav

  @brief Simple-minded package to do traversal.

  @author Fabio Somenzi

  @copyright@parblock
  Copyright (c) 1995-2015, Regents of the University of Colorado

  All rights reserved.

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:

  Redistributions of source code must retain the above copyright
  notice, this list of conditions and the following disclaimer.

  Redistributions in binary form must reproduce the above copyright
  notice, this list of conditions and the following disclaimer in the
  documentation and/or other materials provided with the distribution.

  Neither the name of the University of Colorado nor the names of its
  contributors may be used to endorse or promote products derived from
  this software without specific prior written permission.

  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  POSSIBILITY OF SUCH DAMAGE.
  @endparblock

*/

#ifndef _NTR
#define _NTR

/*---------------------------------------------------------------------------*/
/* Nested includes                                                           */
/*---------------------------------------------------------------------------*/

#include "dddmp.h"
#include "bnet.h"

#ifdef __cplusplus
extern "C" {
#endif

/*---------------------------------------------------------------------------*/
/* Constant declarations                                                     */
/*---------------------------------------------------------------------------*/

#define PI_PS_FROM_FILE	0
#define PI_PS_DFS	1
#define PI_PS_GIVEN	2

#define NTR_IMAGE_MONO 0
#define NTR_IMAGE_PART 1
#define NTR_IMAGE_CLIP 2
#define NTR_IMAGE_DEPEND 3

#define NTR_UNDER_APPROX 0
#define NTR_OVER_APPROX 1

#define NTR_FROM_NEW 0
#define NTR_FROM_REACHED 1
#define NTR_FROM_RESTRICT 2
#define NTR_FROM_COMPACT 3
#define NTR_FROM_SQUEEZE 4
#define NTR_FROM_UNDERAPPROX 5
#define NTR_FROM_OVERAPPROX 6

#define NTR_GROUP_NONE 0
#define NTR_GROUP_DEFAULT 1
#define NTR_GROUP_FIXED 2

#define NTR_SHORT_NONE 0
#define NTR_SHORT_BELLMAN 1
#define NTR_SHORT_FLOYD 2
#define NTR_SHORT_SQUARE 3

/*---------------------------------------------------------------------------*/
/* Stucture declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Type declarations                                                         */
/*---------------------------------------------------------------------------*/

/**
   @brief Options for nanotrav.
*/
typedef	struct	NtrOptions {
    long	initialTime;	/**< this is here for convenience */
    int		verify;		/**< read two networks and compare them */
    char	*file1;		/**< first network file name */
    char	*file2;		/**< second network file name */
    int		second;		/**< a second network is given */
    int		traverse;	/**< do reachability analysis */
    int		depend;		/**< do latch dependence analysis */
    int		image;		/**< monolithic, partitioned, or clip */
    double	imageClip;	/**< clipping depth in image computation */
    int		approx;		/**< under or over approximation */
    int		threshold;	/**< approximation threshold */
    int		from;		/**< method to compute from states */
    int		groupnsps;	/**< group present state and next state vars */
    int		closure;	/**< use transitive closure */
    double	closureClip;	/**< clipping depth in closure computation */
    int		envelope;	/**< compute outer envelope */
    int		scc;		/**< compute strongly connected components */
    int		zddtest;	/**< do zdd test */
    int		printcover;	/**< print ISOP covers when testing ZDDs */
    int		maxflow;	/**< compute maximum flow in network */
    int		shortPath;	/**< compute shortest paths in network */
    int		selectiveTrace;	/**< use selective trace in shortest paths */
    char	*sinkfile;	/**< file for externally provided sink node */
    int		partition;	/**< test McMillan conjunctive partitioning */
    int		char2vect;	/**< test char-to-vect decomposition */
    int		density;	/**< test density-related functions */
    double	quality;	/**< quality parameter for density functions */
    int		decomp;		/**< test decomposition functions */
    int		cofest;		/**< test cofactor estimation */
    double	clip;		/**< test clipping functions */
    int		dontcares;	/**< test equivalence and containment with DCs */
    int		closestCube;	/**< test Cudd_bddClosestCube */
    int		clauses;	/**< test extraction of two-literal clauses */
    int		noBuild;	/**< do not build BDDs; just echo order */
    int		stateOnly;	/**< ignore primary outputs */
    char	*node;		/**< only node for which to build %BDD */
    int		locGlob;	/**< build global or local BDDs */
    int		progress;	/**< report output names while building BDDs */
    int		cacheSize;	/**< computed table initial size */
    size_t	 maxMemory;	/**< target maximum memory */
    size_t	 maxMemHard;	/**< maximum allowed memory */
    unsigned int maxLive;	/**< maximum number of nodes */
    int		slots;		/**< unique subtable initial slots */
    int		ordering;	/**< FANIN DFS ... */
    char	*orderPiPs;	/**< file for externally provided order */
    Cudd_ReorderingType	reordering; /**< NONE RANDOM PIVOT SIFTING ... */
    int		autoDyn;	/**< ON OFF */
    Cudd_ReorderingType autoMethod; /**< RANDOM PIVOT SIFTING CONVERGE ... */
    char	*treefile;	/**< file name for variable tree */
    int		firstReorder;	/**< when to do first reordering */
    int		countDead;	/**< count dead nodes toward triggering
				     reordering */
    int		maxGrowth;	/**< maximum growth during reordering (%) */
    Cudd_AggregationType groupcheck; /**< grouping function */
    int		arcviolation;   /**< percent violation of arcs in
				     extended symmetry check */
    int		symmviolation;  /**< percent symm violation in
				     extended symmetry check */
    int		recomb;		/**< recombination parameter for grouping */
    int		nodrop;		/**< don't drop intermediate BDDs ASAP */
    int		signatures;	/**< computation of signatures */
    int		gaOnOff;	/**< whether to run GA at the end */
    int		populationSize;	/**< population size for GA */
    int		numberXovers;	/**< number of crossovers for GA */
    int		bdddump;	/**< ON OFF */
    int		dumpFmt;	/**< 0 -> dot 1 -> blif 2 ->daVinci 3 -> DDcal
				 ** 4 -> factored form */
    char	*dumpfile;	/**< filename for dump */
    int		store;		/**< iteration at which to store Reached */
    char	*storefile;	/**< filename for storing Reached */
    int		load;		/**< load initial states from file */
    char	*loadfile;	/**< filename for loading states */
    int		verb;		/**< level of verbosity */
    int32_t	seed;		/**< seed for random number generator */
} NtrOptions;

/**
   @brief Type of entry of NtrHeap.
*/
typedef struct NtrHeapSlot NtrHeapSlot;

/**
   @brief Type of heap-based priority queue.
*/
typedef struct NtrHeap NtrHeap;

/**
   @brief Data structure for partitioned transition relation.
*/
typedef struct NtrPartTR {
    int nparts;			/**< number of parts */
    DdNode **part;		/**< array of parts */
    DdNode **icube;		/**< quantification cubes for image */
    DdNode **pcube;		/**< quantification cubes for preimage */
    DdNode **nscube;		/**< next state variables in each part */
    DdNode *preiabs;		/**< present state vars and inputs in no part */
    DdNode *prepabs;		/**< inputs in no part */
    DdNode *xw;			/**< cube of all present states and PIs */
    NtrHeap *factors;		/**< factors extracted from the image */
    int nlatches;		/**< number of latches */
    DdNode **x;			/**< array of present state variables */
    DdNode **y;			/**< array of next state variables */
} NtrPartTR;

/*---------------------------------------------------------------------------*/
/* Variable declarations                                                     */
/*---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*/
/* Macro declarations                                                        */
/*---------------------------------------------------------------------------*/

#ifndef TRUE
#   define TRUE 1
#endif
#ifndef FALSE
#   define FALSE 0
#endif

/**
  @brief Returns 1 if the two arguments are identical strings.

  @sideeffect none

*/
#define STRING_EQUAL(s1,s2) (strcmp((s1),(s2)) == 0)


/** \cond */

/*---------------------------------------------------------------------------*/
/* Function prototypes                                                       */
/*---------------------------------------------------------------------------*/

extern int Ntr_buildDDs (BnetNetwork *net, DdManager *dd, NtrOptions *option, BnetNetwork *net2);
extern NtrPartTR * Ntr_buildTR (DdManager *dd, BnetNetwork *net, NtrOptions *option, int image);
extern DdNode * Ntr_TransitiveClosure (DdManager *dd, NtrPartTR *TR, NtrOptions *option);
extern int Ntr_Trav (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern int Ntr_SCC (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern int Ntr_ClosureTrav (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern void Ntr_freeTR (DdManager *dd, NtrPartTR *TR);
extern NtrPartTR * Ntr_cloneTR (NtrPartTR *TR);
extern DdNode * Ntr_initState (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern DdNode * Ntr_getStateCube (DdManager *dd, BnetNetwork *net, char *filename, int pr);
extern int Ntr_Envelope (DdManager *dd, NtrPartTR *TR, FILE *dfp, NtrOptions *option);
extern int Ntr_TestMinimization (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option);
extern int Ntr_TestDensity (DdManager *dd, BnetNetwork *net1, NtrOptions *option);
extern int Ntr_TestDecomp (DdManager *dd, BnetNetwork *net1, NtrOptions *option);
extern int Ntr_VerifyEquivalence (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option);
extern int Ntr_TestCofactorEstimate (DdManager * dd, BnetNetwork * net, NtrOptions * option);
extern int Ntr_TestClipping (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option);
extern int Ntr_TestEquivAndContain (DdManager *dd, BnetNetwork *net1, BnetNetwork *net2, NtrOptions *option);
extern int Ntr_TestClosestCube (DdManager * dd, BnetNetwork * net, NtrOptions * option);
extern int Ntr_TestTwoLiteralClauses (DdManager * dd, BnetNetwork * net1, NtrOptions * option);
extern int Ntr_TestCharToVect(DdManager * dd, BnetNetwork * net1, NtrOptions * option);
extern int Ntr_maxflow (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern double Ntr_maximum01Flow (DdManager *bdd, DdNode *sx, DdNode *ty, DdNode *E, DdNode **F, DdNode **cut, DdNode **x, DdNode **y, DdNode **z, int n, int pr);
extern int Ntr_testZDD (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern int Ntr_testISOP (DdManager *dd, BnetNetwork *net, NtrOptions *option);
extern NtrHeap * Ntr_InitHeap (int size);
extern void Ntr_FreeHeap (NtrHeap *heap);
extern int Ntr_HeapInsert (NtrHeap *heap, void *item, int key);
extern int Ntr_HeapExtractMin (NtrHeap *heap, void *item, int *key);
extern int Ntr_HeapCount (NtrHeap *heap);
extern NtrHeap * Ntr_HeapClone (NtrHeap *source);
extern void Ntr_HeapForeach (NtrHeap *heap, void (*f)(void *e, void *arg), void *arg);
extern int Ntr_TestHeap (NtrHeap *heap, int i);
extern int Ntr_ShortestPaths (DdManager *dd, BnetNetwork *net, NtrOptions *option);

/** \endcond */


#ifdef __cplusplus
}
#endif

#endif /* _NTR */