/*
 *  espresso.h -- header file for Espresso-mv
 */
#ifndef ESPRESSO_MV_H_65464654616146576541656761767
#define ESPRESSO_MV_H_65464654616146576541656761767

#include "port.h"
#include "utility.h"
#include "sparse.h"
#include "mincov.h"
#include "EspressoStructs.h"

#define ptime()		util_cpu_time()
#define print_time(t)	util_print_time(t)

#undef NO_INLINE

/* MM: presunute do "EspressoStructs.h" */
//#ifdef IBM_WATC
//#define void int
//#include "short.h"
//#endif

#ifdef IBMPC		/* set default options for IBM/PC */
#define NO_INLINE
#define BPI 16
#endif

/*-----THIS USED TO BE set.h----- */

/*
 *  set.h -- definitions for packed arrays of bits
 *
 *   This header file describes the data structures which comprise a
 *   facility for efficiently implementing packed arrays of bits
 *   (otherwise known as sets, cf. Pascal).
 *
 *   A set is a vector of bits and is implemented here as an array of
 *   unsigned integers.  The low order bits of set[0] give the index of
 *   the last word of set data.  The higher order bits of set[0] are
 *   used to store data associated with the set.  The set data is
 *   contained in elements set[1] ... set[LOOP(set)] as a packed bit
 *   array.
 *
 *   A family of sets is a two-dimensional matrix of bits and is
 *   implemented with the data type "set_family".
 *
 *   BPI == 32 and BPI == 16 have been tested and work.
 */


/* Define host machine characteristics of "unsigned int" */
#ifndef BPI
#define BPI             32              /* # bits per integer */
#endif

#if BPI == 32
#define LOGBPI          5               /* log(BPI)/log(2) */
#else
#define LOGBPI          4               /* log(BPI)/log(2) */
#endif

/* Define the set type */
/* MM: presunute do "EspressoStructs.h" */
//typedef unsigned int *pset;

/* Define the set family type -- an array of sets */
/* MM: presunute do "EspressoStructs.h" */
//typedef struct set_family {
//    int wsize;                  /* Size of each set in 'ints' */
//    int sf_size;                /* User declared set size */
//    int capacity;               /* Number of sets allocated */
//    int count;                  /* The number of sets in the family */
//    int active_count;           /* Number of "active" sets */
//    pset data;                  /* Pointer to the set data */
//    struct set_family *next;    /* For garbage collection */
//} set_family_t, *pset_family;

/* Macros to set and test single elements */
#define WHICH_WORD(element)     (((element) >> LOGBPI) + 1)
#define WHICH_BIT(element)      ((element) & (BPI-1))

/* # of ints needed to allocate a set with "size" elements */
#if BPI == 32
#define SET_SIZE(size)          ((size) <= BPI ? 2 : (WHICH_WORD((size)-1) + 1))
#else
#define SET_SIZE(size)          ((size) <= BPI ? 3 : (WHICH_WORD((size)-1) + 2))
#endif

/*
 *  Three fields are maintained in the first word of the set
 *      LOOP is the index of the last word used for set data
 *      LOOPCOPY is the index of the last word in the set
 *      SIZE is available for general use (e.g., recording # elements in set)
 *      NELEM retrieves the number of elements in the set
 */
#define LOOP(set)               (set[0] & 0x03ff)
#define PUTLOOP(set, i)         (set[0] &= ~0x03ff, set[0] |= (i))
#if BPI == 32
#define LOOPCOPY(set)           LOOP(set)
#define SIZE(set)               (set[0] >> 16)
#define PUTSIZE(set, size)      (set[0] &= 0xffff, set[0] |= ((size) << 16))
#else
#define LOOPCOPY(set)           (LOOP(set) + 1)
#define SIZE(set)               (set[LOOP(set)+1])
#define PUTSIZE(set, size)      ((set[LOOP(set)+1]) = (size))
#endif

#define NELEM(set)		(BPI * LOOP(set))
#define LOOPINIT(size)		((size <= BPI) ? 1 : WHICH_WORD((size)-1))

/*
 *      FLAGS store general information about the set
 */
#define SET(set, flag)          (set[0] |= (flag))
#define RESET(set, flag)        (set[0] &= ~ (flag))
#define TESTP(set, flag)        (set[0] & (flag))

/* Flag definitions are ... */
#define PRIME           0x8000          /* cube is prime */
#define NONESSEN        0x4000          /* cube cannot be essential prime */
#define ACTIVE          0x2000          /* cube is still active */
#define REDUND          0x1000          /* cube is redundant(at this point) */
#define COVERED         0x0800          /* cube has been covered */
#define RELESSEN        0x0400          /* cube is relatively essential */

/* Most efficient way to look at all members of a set family */
#define foreach_set(R, last, p)\
    for(p=R->data,last=p+R->count*R->wsize;p<last;p+=R->wsize)
#define foreach_remaining_set(R, last, pfirst, p)\
    for(p=pfirst+R->wsize,last=R->data+R->count*R->wsize;p<last;p+=R->wsize)
#define foreach_active_set(R, last, p)\
    foreach_set(R,last,p) if (TESTP(p, ACTIVE))

/* Another way that also keeps the index of the current set member in i */
#define foreachi_set(R, i, p)\
    for(p=R->data,i=0;i<R->count;p+=R->wsize,i++)
#define foreachi_active_set(R, i, p)\
    foreachi_set(R,i,p) if (TESTP(p, ACTIVE))

/* Looping over all elements in a set:
 *      foreach_set_element(pset p, int i, unsigned val, int base) {
 *		.
 *		.
 *		.
 *      }
 */
#define foreach_set_element(p, i, val, base) 		\
    for(i = LOOP(p); i > 0; )				\
	for(val = p[i], base = --i << LOGBPI; val != 0; base++, val >>= 1)  \
	    if (val & 1)

/* Return a pointer to a given member of a set family */
#define GETSET(family, index)   ((family)->data + (family)->wsize * (index))

/* Allocate and deallocate sets */
#define set_new(size)	set_clear(ALLOC(unsigned int, SET_SIZE(size)), size)
#define set_full(size)	set_fill(ALLOC(unsigned int, SET_SIZE(size)), size)
#define set_save(r)	set_copy(ALLOC(unsigned int, SET_SIZE(NELEM(r))), r)
#define set_free(r)	FREE(r)

/* Check for set membership, remove set element and insert set element */
#define is_in_set(set, e)       (set[WHICH_WORD(e)] & (1 << WHICH_BIT(e)))
#define set_remove(set, e)      (set[WHICH_WORD(e)] &= ~ (1 << WHICH_BIT(e)))
#define set_insert(set, e)      (set[WHICH_WORD(e)] |= 1 << WHICH_BIT(e))

/* Inline code substitution for those places that REALLY need it on a VAX */
#ifdef NO_INLINE
#define INLINEset_copy(r, a)		(void) set_copy(r,a)
#define INLINEset_clear(r, size)	(void) set_clear(r, size)
#define INLINEset_fill(r, size)		(void) set_fill(r, size)
#define INLINEset_and(r, a, b)		(void) set_and(r, a, b)
#define INLINEset_or(r, a, b)		(void) set_or(r, a, b)
#define INLINEset_diff(r, a, b)		(void) set_diff(r, a, b)
#define INLINEset_ndiff(r, a, b, f)	(void) set_ndiff(r, a, b, f)
#define INLINEset_xor(r, a, b)		(void) set_xor(r, a, b)
#define INLINEset_xnor(r, a, b, f)	(void) set_xnor(r, a, b, f)
#define INLINEset_merge(r, a, b, mask)	(void) set_merge(r, a, b, mask)
#define INLINEsetp_implies(a, b, when_false)	\
    if (! setp_implies(a,b)) when_false
#define INLINEsetp_disjoint(a, b, when_false)	\
    if (! setp_disjoint(a,b)) when_false
#define INLINEsetp_equal(a, b, when_false)	\
    if (! setp_equal(a,b)) when_false

#else

#define INLINEset_copy(r, a)\
    {register int i_=LOOPCOPY(a); do r[i_]=a[i_]; while (--i_>=0);}
#define INLINEset_clear(r, size)\
    {register int i_=LOOPINIT(size); *r=i_; do r[i_] = 0; while (--i_ > 0);}
#define INLINEset_fill(r, size)\
    {register int i_=LOOPINIT(size); *r=i_; \
    r[i_]=((unsigned int)(~0))>>(i_*BPI-size); while(--i_>0) r[i_]=~0;}
#define INLINEset_and(r, a, b)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = a[i_] & b[i_]; while (--i_>0);}
#define INLINEset_or(r, a, b)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = a[i_] | b[i_]; while (--i_>0);}
#define INLINEset_diff(r, a, b)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = a[i_] & ~ b[i_]; while (--i_>0);}
#define INLINEset_ndiff(r, a, b, fullset)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = fullset[i_] & (a[i_] | ~ b[i_]); while (--i_>0);}
#ifdef IBM_WATC
#define INLINEset_xor(r, a, b)		(void) set_xor(r, a, b)
#define INLINEset_xnor(r, a, b, f)	(void) set_xnor(r, a, b, f)
#else
#define INLINEset_xor(r, a, b)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = a[i_] ^ b[i_]; while (--i_>0);}
#define INLINEset_xnor(r, a, b, fullset)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = fullset[i_] & ~ (a[i_] ^ b[i_]); while (--i_>0);}
#endif
#define INLINEset_merge(r, a, b, mask)\
    {register int i_=LOOP(a); PUTLOOP(r,i_);\
    do r[i_] = (a[i_]&mask[i_]) | (b[i_]&~mask[i_]); while (--i_>0);}
#define INLINEsetp_implies(a, b, when_false)\
    {register int i_=LOOP(a); do if (a[i_]&~b[i_]) break; while (--i_>0);\
    if (i_ != 0) when_false;}
#define INLINEsetp_disjoint(a, b, when_false)\
    {register int i_=LOOP(a); do if (a[i_]&b[i_]) break; while (--i_>0);\
    if (i_ != 0) when_false;}
#define INLINEsetp_equal(a, b, when_false)\
    {register int i_=LOOP(a); do if (a[i_]!=b[i_]) break; while (--i_>0);\
    if (i_ != 0) when_false;}

#endif

#if BPI == 32
#define count_ones(v)\
    (bit_count[v & 255] + bit_count[(v >> 8) & 255]\
    + bit_count[(v >> 16) & 255] + bit_count[(v >> 24) & 255])
#else
#define count_ones(v)   (bit_count[v & 255] + bit_count[(v >> 8) & 255])
#endif

/* Table for efficient bit counting */
extern int bit_count[256];
/*----- END OF set.h ----- */

/* Define a boolean type */
/** MM: presunute do "EspressoStructs.h" */
//#define bool3	int
//#define FALSE3	0
//#define TRUE3 	1
//#define MAYBE3	2
//#define print_bool(x) ((x) == 0 ? "FALSE" : ((x) == 1 ? "TRUE" : "MAYBE"))

/* Map many cube/cover types/routines into equivalent set types/routines */
/** MM: presunute do "EspressoStructs.h" */
//#define pcube                   pset
#define new_cube()              set_new(cube->size)
#define free_cube(r)            set_free(r)
/** MM: presunute do "EspressoStructs.h" */
//#define pcover                  pset_family
#define new_cover(i)            sf_new(i, cube->size)
#define free_cover(r)           sf_free(r)
#define free_cubelist(T)        FREE(T[0]); FREE(T);


/* cost_t describes the cost of a cover */
typedef struct cost_struct {
    int cubes;			/* number of cubes in the cover */
    int in;			/* transistor count, binary-valued variables */
    int out;			/* transistor count, output part */
    int mv;			/* transistor count, multiple-valued vars */
    int total;			/* total number of transistors */
    int primes;			/* number of prime cubes */
} cost_t, *pcost;


/* pair_t describes bit-paired variables */
/** MM: presunute do "EspressoStructs.h" */
//typedef struct pair_struct {
//    int cnt;
//    int *var1;
//    int *var2;
//} pair_t, *ppair;

/* symbolic_list_t describes a single ".symbolic" line */
/** MM: presunute do "EspressoStructs.h" */
//typedef struct symbolic_list_struct {
//    int variable;
//    int pos;
//    struct symbolic_list_struct *next;
//} symbolic_list_t;


/* symbolic_list_t describes a single ".symbolic" line */
/** MM: presunute do "EspressoStructs.h" */
//typedef struct symbolic_label_struct {
//    char *label;
//    struct symbolic_label_struct *next;
//} symbolic_label_t;


/* symbolic_t describes a linked list of ".symbolic" lines */
/** MM: presunute do "EspressoStructs.h" */
//typedef struct symbolic_struct {
//    symbolic_list_t *symbolic_list;	/* linked list of items */
//    int symbolic_list_length;		/* length of symbolic_list list */
//    symbolic_label_t *symbolic_label;	/* linked list of new names */
//    int symbolic_label_length;		/* length of symbolic_label list */
//    struct symbolic_struct *next;
//} symbolic_t;


/* PLA_t stores the logical representation of a PLA */
/* MM: presunute do "EspressoStructs.h" */
//typedef struct {
//    pcover F, D, R;		/* on-set, off-set and dc-set */
//    char *filename;             /* filename */
//    int pla_type;               /* logical PLA format */
//    pcube phase;                /* phase to split into on-set and off-set */
//    ppair pair;                 /* how to pair variables */
//    char **label;		/* labels for the columns */
//    symbolic_t *symbolic;	/* allow binary->symbolic mapping */
//    symbolic_t *symbolic_output;/* allow symbolic output mapping */
//} PLA_t, *pPLA;

#define str_equal(a,b)      (strcmp(a,b) == 0)

/* This is a hack which I wish I hadn't done, but too painful to change */
#define CUBELISTSIZE(T)         (((pcube *) T[1] - T) - 3)

/* For documentation purposes */
#define IN
#define OUT
#define INOUT

/* The pla_type field describes the input and output format of the PLA */
#define F_type          1
#define D_type          2
#define R_type          4
#define PLEASURE_type   8               /* output format */
#define EQNTOTT_type    16              /* output format algebraic eqns */
#define KISS_type	128		/* output format kiss */
#define CONSTRAINTS_type	256	/* output the constraints (numeric) */
#define SYMBOLIC_CONSTRAINTS_type 512	/* output the constraints (symbolic) */
#define FD_type (F_type | D_type)
#define FR_type (F_type | R_type)
#define DR_type (D_type | R_type)
#define FDR_type (F_type | D_type | R_type)

/* Definitions for the debug variable */
#define COMPL           0x0001
#define ESSEN           0x0002
#define EXPAND          0x0004
#define EXPAND1         0x0008
#define GASP            0x0010
#define IRRED           0x0020
#define REDUCE          0x0040
#define REDUCE1         0x0080
#define SPARSE          0x0100
#define TAUT            0x0200
#define EXACT           0x0400
#define MINCOV          0x0800
#define MINCOV1         0x1000
#define SHARP           0x2000
#define IRRED1		    0x4000

/* Define constants used for recording program statistics */
#define TIME_COUNT      22
#define READ_TIME       0
#define COMPL_TIME      1
#define ONSET_TIME      2
#define ESSEN_TIME      3
#define EXPAND_TIME     4
#define IRRED_TIME      5
#define REDUCE_TIME     6
#define GEXPAND_TIME    7
#define GIRRED_TIME     8
#define GREDUCE_TIME    9
#define PRIMES_TIME     10
#define MINCOV_TIME     11
#define MV_REDUCE_TIME  12
#define RAISE_IN_TIME   13
#define VERIFY_TIME     14
#define WRITE_TIME	15
#define FCC_TIME	16
#define ETR_TIME	17
#define ETRAUX_TIME	18
#define SIGMA_TIME	19
#define UCOMP_TIME	20
#define BW_TIME		21

/* For those who like to think about PLAs, macros to get at inputs/outputs */
#define NUMINPUTS       cube->num_binary_vars
#define NUMOUTPUTS      cube->part_size[cube->num_vars - 1]

#define INLABEL(var)    PLA->label[cube->first_part[var] + 1]
#define OUTLABEL(pos)   PLA->label[cube->first_part[cube->output] + pos]

#define GETINPUT(c, pos)\
    ((c[WHICH_WORD(2*pos)] >> WHICH_BIT(2*pos)) & 3)
#define GETOUTPUT(c, pos)\
    (is_in_set(c, cube->first_part[cube->output] + pos) != 0)

#define PUTINPUT(c, pos, value)\
    c[WHICH_WORD(2*pos)] = (c[WHICH_WORD(2*pos)] & ~(3 << WHICH_BIT(2*pos)))\
		| (value << WHICH_BIT(2*pos))
#define PUTOUTPUT(c, pos, value)\
    c[WHICH_WORD(pos)] = (c[WHICH_WORD(pos)] & (1 << WHICH_BIT(pos)))\
		| (value << WHICH_BIT(pos))

#define TWO     3
#define DASH    3
#define ONE     2
#define ZERO    1


#define EXEC(fct, name, S)\
    {long t=ptime();fct;if(trace)print_trace(S,name,ptime()-t);}
#define EXEC_S(fct, name, S)\
    {long t=ptime();fct;if(summary)print_trace(S,name,ptime()-t);}
#define EXECUTE(fct,i,S,cost)\
    {long t=ptime();fct;totals(t,i,S,&(cost));}
/* lightweight EXECUTE */
#define S_EXECUTE(fct,i)\
    {long t=ptime();fct;s_totals(t,i);}

/*
 *    Global Variable Declarations
 */
/** MM: umiestnene v globals.cpp okrem debug_exact_minimization [ODSTRANENA] */

extern unsigned int debug;              /* debug parameter */
extern bool3 verbose_debug;              /* -v:  whether to print a lot */
extern char *total_name[TIME_COUNT];    /* basic function names */
extern long total_time[TIME_COUNT];     /* time spent in basic fcts */
extern int total_calls[TIME_COUNT];     /* # calls to each fct */

extern bool3 echo_comments;		/* turned off by -eat option */
extern bool3 echo_unknown_commands;	/* always true ?? */
extern bool3 force_irredundant;          /* -nirr command line option */
extern bool3 skip_make_sparse;
extern bool3 kiss;                       /* -kiss command line option */
extern bool3 recompute_onset;            /* -onset command line option */
extern bool3 remove_essential;           /* -ness command line option */
extern bool3 single_expand;              /* -fast command line option */
extern bool3 summary;                    /* -s command line option */
extern bool3 trace;                      /* -t command line option */
extern bool3 unwrap_onset;               /* -nunwrap command line option */
extern bool3 use_random_order;		/* -random command line option */
extern bool3 use_super_gasp;		/* -strong command line option */
extern char *filename;			/* filename PLA was read from */

extern bool3 toggle; /** MM: povodne staticka premenna inicializovana na zaciatku modulu reduce */

extern const char octtools_copyright[]; /* MM: OCCTOOLS copyright */
extern const char* VERSION;


/** MM: added to support various outputs */
extern FILE* tracesumoutput;
extern FILE* debugoutput;
extern FILE* erroroutput;
extern FILE* eatoutput;
extern FILE* eatdotsoutput;
extern FILE* standardoutput;

/*
 *  pla_types are the input and output types for reading/writing a PLA
 */
struct pla_types_struct {
    char *key;
    int value;
};


/*
 *  The cube structure is a global structure which contains information
 *  on how a set maps into a cube -- i.e., number of parts per variable,
 *  number of variables, etc.  Also, many fields are pre-computed to
 *  speed up various primitive operations.
 */
#define CUBE_TEMP       10
/* MM: presunute do "EspressoStructs.h" */
//struct cube_struct {
//    int size;                   /* set size of a cube */
//    int num_vars;               /* number of variables in a cube */
//    int num_binary_vars;        /* number of binary variables */
//    int *first_part;            /* first element of each variable */
//    int *last_part;             /* first element of each variable */
//    int *part_size;             /* number of elements in each variable */
//    int *first_word;            /* first word for each variable */
//    int *last_word;             /* last word for each variable */
//    pset binary_mask;           /* Mask to extract binary variables */
//    pset mv_mask;               /* mask to get mv parts */
//    pset *var_mask;             /* mask to extract a variable */
//    pset *temp;                 /* an array of temporary sets */
//    pset fullset;               /* a full cube */
//    pset emptyset;              /* an empty cube */
//    unsigned int inmask;        /* mask to get odd word of binary part */
//    int inword;                 /* which word number for above */
//    int *sparse;                /* should this variable be sparse? */
//    int num_mv_vars;            /* number of multiple-valued variables */
//    int output;                 /* which variable is "output" (-1 if none) */
//};

/* MM: presunute do "EspressoStructs.h" */
//struct cdata_struct {
//    int *part_zeros;            /* count of zeros for each element */
//    int *var_zeros;             /* count of zeros for each variable */
//    int *parts_active;          /* number of "active" parts for each var */
//    bool3 *is_unate;             /* indicates given var is unate */
//    int vars_active;            /* number of "active" variables */
//    int vars_unate;             /* number of unate variables */
//    int best;                   /* best "binate" variable */
//};


extern struct pla_types_struct pla_types[];
extern struct cube_struct *cube;
extern struct cdata_struct *cdata;

#ifdef lint
#define DISJOINT 0x5555
#else
#if BPI == 32
#define DISJOINT 0x55555555
#else
#define DISJOINT 0x5555
#endif
#endif

/* function declarations */

/* cofactor.c */	extern int binate_split_select(pset *T, register pset cleft, register pset cright, int debug_flag);
/* cofactor.c */	extern pcover cubeunlist(pset *A1);
/* cofactor.c */	extern pcube *cofactor(pset *T, register pset c);
/* cofactor.c */	extern pcube *cube1list(pset_family A);
/* cofactor.c */	extern pcube *cube2list(pset_family A, pset_family B);
/* cofactor.c */	extern pcube *cube3list(pset_family A, pset_family B, pset_family C);
/* cofactor.c */	extern pcube *scofactor(pset *T, pset c, int var);
/* cofactor.c */	extern void massive_count(pset *T);
/* compl.c */	extern pcover complement(pset *T);
/* compl.c */	extern pcover simplify(pset *T);
/* compl.c */	extern int simp_comp(pset *T, pset_family *Tnew, pset_family *Tbar); /** MM: int pre kontrolu chyby */
/* contain.c */	extern int d1_rm_equal(register pset *A1, int (*compare) (const void *a, const void *b) );
/* contain.c */	extern int rm2_contain(pset *A1, pset *B1);
/* contain.c */	extern int rm2_equal(register pset *A1, register pset *B1, pset *E1, int (*compare) (const void *a, const void *b) );
/* contain.c */	extern int rm_contain(pset *A1);
/* contain.c */	extern int rm_equal(pset *A1, int (*compare) (const void *a, const void *b) );
/* contain.c */	extern int rm_rev_contain(pset *A1);
/* contain.c */	extern pset *sf_list(register pset_family A);
/* contain.c */	extern pset *sf_sort(pset_family A, int (*compare) (const void *a, const void *b) );
/* contain.c */	extern pset_family d1merge(pset_family A, int var);
/* contain.c */	extern pset_family dist_merge(pset_family A, pset mask);
/* contain.c */	extern pset_family sf_contain(pset_family A);
/* contain.c */	extern pset_family sf_dupl(pset_family A);
/* contain.c */	extern pset_family sf_merge(pset *A1, pset *B1, pset *E1, int totcnt, int size);
/* contain.c */	extern pset_family sf_rev_contain(pset_family A);
/* contain.c */	extern pset_family sf_union(pset_family A, pset_family B);
/* contain.c */	extern pset_family sf_union_no_dispose(pset_family A, pset_family B); /** MM: verzia, ktora nemusi zalohovat A a B */
/* contain.c */	extern pset_family sf_union_no_dispose(pset_family A, pset_family B); /** MM: vytvorene kvoli unionu 2 PLA */
/* contain.c */	extern pset_family sf_unlist(pset *A1, int totcnt, int size);
/* cubestr.c */	extern int cube_setup(void);
/* cubestr.c */	extern void setdown_cube(void);
/* cubestr.c */	extern int setdown_cube(cube_struct* c, struct cdata_struct *d); /** MM: funkcia pre setdown hocijakej, nie len aktualnej cube a cdata struct */
/* cvrin.c */	extern int PLA_labels(pPLA PLA); /** MM: int na detekciu chyby */
/* cvrin.c */	extern char *get_word(register FILE *fp, register char *word);
/* cvrin.c */	extern int label_index(pPLA PLA, char *word, int *varp, int *ip);
/* cvrin.c */	extern int read_pla(FILE *fp, pPLA PLA);
/* cvrin.c */	extern int read_pla_string(const char **stringPtr, pPLA PLA);
/* cvrin.c */	extern int read_symbolic(FILE *fp, pPLA PLA, char *word, symbolic_t **retval);
/* cvrin.c */	extern pPLA new_PLA(void);
/* cvrin.c */	extern int PLA_summary(pPLA PLA, FILE* target); /** MM: int na detekciu chyby */
/* cvrin.c */	extern void free_PLA(pPLA PLA);
/* cvrin.c */	extern int parse_pla(FILE *fp, pPLA PLA); /** MM: int na detekciu chyby */
/* cvrin.c */	extern int read_cube(register FILE *fp, pPLA PLA); /** MM: int na detekciu chyby */
/* cvrin.c */	extern void skip_line(register FILE *fpin, register FILE *fpout, register int echo);
/* cvrm.c */	extern int foreach_output_function(pPLA PLA, int (*func) (pPLA PLA, int i), int (*func1) (pPLA PLA, int i) ); /** MM: int na detekciu chyby */
/* cvrm.c */	extern int cubelist_partition(pset *T, pset **A, pset **B, unsigned int comp_debug);
/* cvrm.c */	extern int so_both_do_espresso(pPLA PLA, int i);
/* cvrm.c */	extern int so_both_do_exact(pPLA PLA, int i);
/* cvrm.c */	extern int so_both_save(pPLA PLA, int i);
/* cvrm.c */	extern int so_do_espresso(pPLA PLA, int i);
/* cvrm.c */	extern int so_do_exact(pPLA PLA, int i);
/* cvrm.c */	extern int so_save(pPLA PLA, int i);
/* cvrm.c */	extern pcover cof_output(pset_family T, register int i);
/* cvrm.c */	extern pcover lex_sort(pset_family T);
/* cvrm.c */	extern pcover mini_sort(pset_family F, int (*compare) (const void *a, const void *b) );
/* cvrm.c */	extern pcover random_order(register pset_family F);
/* cvrm.c */	extern pcover sort_reduce(pset_family T);
/* cvrm.c */	extern pcover uncof_output(pset_family T, int i);
/* cvrm.c */	extern pcover unravel(pset_family B, int start);
/* cvrm.c */	extern pcover unravel_range(pset_family B, int start, int end);
/* cvrm.c */	extern int so_both_espresso(pPLA PLA, int strategy); /** MM: int na detekciu chyby */
/* cvrm.c */	extern int so_espresso(pPLA PLA, int strategy); /** MM: int na detekciu chyby */
/* cvrmisc.c */	extern char *fmt_cost(pcost cost);
/* cvrmisc.c */	extern char *print_cost(pset_family F);
/* cvrmisc.c */	extern void copy_cost(pcost s, pcost d);
/* cvrmisc.c */	extern void cover_cost(pset_family F, pcost cost);
/* cvrmisc.c */	/* extern void fatal(char *s); */ /** MM: pouzitie nahradene fatal2 */
/* cvrmisc.c */	extern void fatal2(char *s);
/* cvrmisc.c */	extern void print_trace(pset_family T, const char *name, long int time);
/* cvrmisc.c */	extern void size_stamp(pset_family T, char *name);
/* cvrmisc.c */	extern void totals(long int time, int i, pset_family T, pcost cost);
/* cvrmisc.c */	extern void runtime(void); /** MM: presunuta z main.cpp */
/* cvrout.c */	extern char *fmt_cube(register pset c, register char *out_map, register char *s);
/* cvrout.c */	extern char *pc1(pset c);
/* cvrout.c */	extern char *pc2(pset c);
/* cvrout.c */	extern void makeup_labels(pPLA PLA);
/* cvrout.c */	extern int kiss_output(FILE *fp, pPLA PLA);
/* cvrout.c */	extern int kiss_print_cube(FILE *fp, pPLA PLA, pset p, char *out_string);
/* cvrout.c */	extern void output_symbolic_constraints(FILE *fp, pPLA PLA, int output_symbolic);
/* cvrout.c */	extern void cprint(pset_family T);
/* cvrout.c */	extern void debug1_print(pset_family T, char *name, int num);
/* cvrout.c */	extern void debug_print(pset *T, char *name, int level);
/* cvrout.c */	extern int eqn_output(pPLA PLA, FILE *fp); /** MM: int na detekciu chyby, pridany fp */
/* cvrout.c */	extern int fpr_header(FILE *fp, pPLA PLA, int output_type); /** MM: int na detekciu chyby */
/* cvrout.c */	extern int fprint_pla(FILE *fp, pPLA PLA, int output_type);
/* cvrout.c */	extern void pls_group(pPLA PLA, FILE *fp);
/* cvrout.c */	extern void pls_label(pPLA PLA, FILE *fp);
/* cvrout.c */	extern int pls_output(pPLA PLA, FILE *fp); /** MM: int na detekciu chyby, pridany fp */
/* cvrout.c */	extern void print_cube(register FILE *fp, register pset c, register char *out_map);
/* cvrout.c */	extern void print_expanded_cube(register FILE *fp, register pset c, pset phase);
/* equiv.c */	extern int find_equiv_outputs(pPLA PLA, FILE *fp); /** MM: int na detekciu chyby, pridany fp */
/* equiv.c */	extern int check_equiv(pset_family f1, pset_family f2);
/* espresso.c */	extern pcover espresso(pset_family F, pset_family D1, pset_family R);
/* essen.c */	extern bool3 essen_cube(pset_family F, pset_family D, pset c);
/* essen.c */	extern pcover cb_consensus(register pset_family T, register pset c);
/* essen.c */	extern pcover cb_consensus_dist0(pset_family R, register pset p, register pset c);
/* essen.c */	extern pcover essential(pset_family *Fp, pset_family *Dp);
/* exact.c */	extern pcover minimize_exact(pset_family F, pset_family D, pset_family R, int exact_cover);
/* exact.c */	extern pcover minimize_exact_literals(pset_family F, pset_family D, pset_family R, int exact_cover);
/* expand.c */	extern bool3 feasibly_covered(pset_family BB, pset c, pset RAISE, pset new_lower);
/* expand.c */	extern int most_frequent(pset_family CC, pset FREESET);
/* expand.c */	extern pcover all_primes(pset_family F, pset_family R);
/* expand.c */	extern pcover expand(pset_family F, pset_family R, int nonsparse);
/* expand.c */	extern pcover find_all_primes(pset_family BB, register pset RAISE, register pset FREESET);
/* expand.c */	extern void elim_lowering(pset_family BB, pset_family CC, pset RAISE, pset FREESET);
/* expand.c */	extern int essen_parts(pset_family BB, pset_family CC, pset RAISE, pset FREESET); /** MM: int na detekciu chyby */
/* expand.c */	extern void essen_raising(register pset_family BB, pset RAISE, pset FREESET);
/* expand.c */	extern int expand1(pset_family BB, pset_family CC, pset RAISE, pset FREESET, pset OVEREXPANDED_CUBE, pset SUPER_CUBE, pset INIT_LOWER, int *num_covered, pset c); /** MM: int na detekciu chyby */
/* expand.c */	extern int mincov(pset_family BB, pset RAISE, pset FREESET); /** MM: int na detekciu chyby */
/* expand.c */	extern int select_feasible(pset_family BB, pset_family CC, pset RAISE, pset FREESET, pset SUPER_CUBE, int *num_covered); /** MM: int na detekciu chyby */
/* expand.c */	extern void setup_BB_CC(register pset_family BB, register pset_family CC);
/* gasp.c */	extern pcover expand_gasp(pset_family F, pset_family D, pset_family R, pset_family Foriginal);
/* gasp.c */	extern pcover irred_gasp(pset_family F, pset_family D, pset_family G);
/* gasp.c */	extern pcover last_gasp(pset_family F, pset_family D, pset_family R, cost_t *cost);
/* gasp.c */	extern pcover super_gasp(pset_family F, pset_family D, pset_family R, cost_t *cost);
/* gasp.c */	extern int expand1_gasp(pset_family F, pset_family D, pset_family R, pset_family Foriginal, int c1index, pset_family *G); /** MM: int na detekciu chyby */
/* hack.c */	extern void find_inputs(pset_family A, pPLA PLA, symbolic_list_t *list, int base, int value, pset_family *newF, pset_family *newD);
/* hack.c */	extern int form_bitvector(pset p, int base, int value, symbolic_list_t *list); /** MM: int na detekciu chyby */
/* hack.c */	extern int map_dcset(pPLA PLA); /** MM: int na detekciu chyby */
/* hack.c */	extern int map_output_symbolic(pPLA PLA); /** MM: int na detekciu chyby */
/* hack.c */	extern int map_symbolic(pPLA PLA); /** MM: int na detekciu chyby */
/* hack.c */	extern pcover map_symbolic_cover(pset_family T, symbolic_list_t *list, int base);
/* hack.c */	extern int symbolic_hack_labels(pPLA PLA, symbolic_t *list, pset compress, int new_size, int old_size, int size_added); /** MM: int na detekciu chyby */
/* irred.c */	extern bool3 cube_is_covered(pset *T, pset c);
/* irred.c */	extern bool3 taut_special_cases(pset *T);
/* irred.c */	extern bool3 tautology(pset *T);
/* irred.c */	extern pcover irredundant(pset_family F, pset_family D);
/* irred.c */	extern int mark_irredundant(pset_family F, pset_family D); /** MM: int na kontrolu chyby */
/* irred.c */	extern void irred_split_cover(pset_family F, pset_family D, pset_family *E, pset_family *Rt, pset_family *Rp);
/* irred.c */	extern sm_matrix *irred_derive_table(pset_family D, pset_family E, pset_family Rp);
/* map.c */	extern pset minterms(pset_family T);
/* map.c */	extern void explode(int var, int z);
/* map.c */	extern int map(pset_family T, FILE *fp); /** MM: int na detekciu chyby, pridany fp */
/* opo.c */	extern int output_phase_setup(pPLA PLA, int first_output); /** MM: int kvoli fatalu */
/* opo.c */	extern pPLA set_phase(pPLA PLA);
/* opo.c */	extern pcover opo(pset phase, pset_family T, pset_family D, pset_family R, int first_output);
/* opo.c */	extern pcube find_phase(pPLA PLA, int first_output, pset phase1);
#if 0
/* opo.c */	extern pset_family find_covers(pcover F, pcover D, register pset select, int n);
/* opo.c */	extern pset_family form_cover_table(pcover F, pcover D, pset select, int f, int fbar);
#endif
/* opo.c */	extern pset_family opo_leaf(register pset_family T, pset select, int out1, int out2);
/* opo.c */	extern pset_family opo_recur(pset_family T, pset_family D, pset select, int offset, int first, int last);
/* opo.c */	extern int opoall(pPLA PLA, int first_output, int last_output, int opo_strategy); /** MM: int na detekciu chyby */
/* opo.c */	extern int phase_assignment(pPLA PLA, int opo_strategy); /** MM: int na detekciu chyby */
/* opo.c */	extern int repeated_phase_assignment(pPLA PLA); /** MM: int na detekciu chyby */
/* pair.c */	extern int generate_all_pairs(ppair pair, int n, pset candidate, int (*action) (register ppair pair) ); /** MM: int na detekciu chyby */
/* pair.c */	extern int **find_pairing_cost(pPLA PLA, int strategy);
/* pair.c */	extern int find_best_cost(register ppair pair); /** MM: int, aby to pasovalo do generate_all_pairs */
/* pair.c */	extern int greedy_best_cost(int **cost_array_local, ppair *pair_p);
/* pair.c */	extern int minimize_pair(ppair pair); /** MM: int na detekciu chyby */
/* pair.c */	extern void pair_free(register ppair pair);
/* pair.c */	extern int pair_all(pPLA PLA, int pair_strategy); /** MM: int na detekciu chyby */
/* pair.c */	extern pcover delvar(pset_family A, int *paired);
/* pair.c */	extern pcover pairvar(pset_family A, ppair pair);
/* pair.c */	extern ppair pair_best_cost(int **cost_array_local);
/* pair.c */	extern ppair pair_new(register int n);
/* pair.c */	extern ppair pair_save(register ppair pair, register int n);
/* pair.c */	extern void print_pair(ppair pair, FILE* fd);
/* pair.c */	extern int find_optimal_pairing(pPLA PLA, int strategy); /** MM: int na detekciu chyby */
/* pair.c */	extern int set_pair(pPLA PLA);
/* pair.c */	extern int set_pair1(pPLA PLA, int adjust_labels);
/* primes.c */	extern pcover primes_consensus(pset *T);
/* reduce.c */	extern bool3 sccc_special_cases(pset *T, pset *result);
/* reduce.c */	extern pcover reduce(pset_family F, pset_family D);
/* reduce.c */	extern pcube reduce_cube(pset *FD, pset p);
/* reduce.c */	extern pcube sccc(pset *T);
/* reduce.c */	extern pcube sccc_cube(register pset result, register pset p);
/* reduce.c */	extern pcube sccc_merge(register pset left, register pset right, register pset cl, register pset cr);
/* set.c */	extern bool3 set_andp(register pset r, register pset a, register pset b);
/* set.c */	extern bool3 setp_disjoint(register pset a, register pset b);
/* set.c */	extern bool3 setp_empty(register pset a);
/* set.c */	extern bool3 setp_equal(register pset a, register pset b);
/* set.c */	extern bool3 setp_implies(register pset a, register pset b);
/* set.c */	extern char *ps1(register pset a);
/* set.c */	extern int *sf_count(pset_family A);
/* set.c */	extern int *sf_count_restricted(pset_family A, register pset r);
/* set.c */	extern int bit_index(register unsigned int a);
/* set.c */	extern int set_dist(register pset a, register pset b);
/* set.c */	extern int set_ord(register pset a);
/* set.c */	extern void set_adjcnt(register pset a, register int *count, register int weight);
/* set.c */	extern pset set_and(register pset r, register pset a, register pset b);
/* set.c */	extern pset set_clear(register pset r, int size);
/* set.c */	extern pset set_copy(register pset r, register pset a);
/* set.c */	extern pset set_diff(register pset r, register pset a, register pset b);
/* set.c */	extern pset set_fill(register pset r, register int size);
/* set.c */	extern pset set_merge(register pset r, register pset a, register pset b, register pset mask);
/* set.c */	extern pset set_or(register pset r, register pset a, register pset b);
/* set.c */	extern pset set_xor(register pset r, register pset a, register pset b);
/* set.c */	extern pset_family sf_active(pset_family A);
/* set.c */	extern pset_family sf_addcol(pset_family A, int firstcol, int n);
/* set.c */	extern pset_family sf_addset(pset_family A, const pset s);
/* set.c */	extern pset_family sf_append(pset_family A, pset_family B);
/* set.c */	extern pset_family sf_compress(pset_family A, register pset c);
/* set.c */	extern pset_family sf_copy(pset_family R, pset_family A);
/* set.c */	extern pset_family sf_copy_col(pset_family dst, int dstcol, pset_family src, int srccol);
/* set.c */	extern pset_family sf_delc(pset_family A, int first, int last);
/* set.c */	extern pset_family sf_delcol(pset_family A, register int firstcol, register int n);
/* set.c */	extern pset_family sf_inactive(pset_family A);
/* set.c */	extern pset_family sf_join(pset_family A, pset_family B);
/* set.c */	extern pset_family sf_new(int num, int size);
/* set.c */	extern pset_family sf_permute(pset_family A, register int *permute, register int npermute);
/* set.c */	extern pset_family sf_save(register pset_family A);
/* set.c */	extern void sf_cleanup(void);
/* set.c */	extern void sf_delset(pset_family A, int i);
/* set.c */	extern void sf_free(pset_family A);
/* set.c */	extern void sf_print(pset_family A);
/* setc.c */	extern bool3 ccommon(register pset a, register pset b, register pset cof);
/* setc.c */	extern bool3 cdist0(register pset a, register pset b);
/* setc.c */	extern bool3 full_row(register pset p, register pset cof);
/* setc.c */	extern int ascend(const void *a, const void *b);
/* setc.c */	extern int cactive(register pset a);
/* setc.c */	extern int cdist(register pset a, register pset b);
/* setc.c */	extern int cdist01(register pset a, register pset b);
/* setc.c */	extern int d1_order(const void *a, const void *b);
/* setc.c */	extern int desc1(register pset a, register pset b);
/* setc.c */	extern int descend(const void *a, const void *b);
/* setc.c */	extern int lex_order(const void *a, const void *b);
/* setc.c */	extern pset force_lower(pset xlower, register pset a, register pset b);
/* setc.c */	extern void consensus(pset r, register pset a, register pset b);
/* sharp.c */	extern pcover cb1_dsharp(pset_family T, pset c);
/* sharp.c */	extern pcover cb_dsharp(pset c, pset_family T);
/* sharp.c */	extern pcover cb_recur_sharp(pset c, pset_family T, int first, int last, int level);
/* sharp.c */	extern pcover cb_sharp(pset c, pset_family T);
/* sharp.c */	extern pcover cv_dsharp(pset_family A, pset_family B);
/* sharp.c */	extern pcover cv_intersect(pset_family A, pset_family B);
/* sharp.c */	extern pcover cv_sharp(pset_family A, pset_family B);
/* sharp.c */	extern pcover dsharp(pset a, pset b);
/* sharp.c */	extern pcover make_disjoint(pset_family A);
/* sharp.c */	extern pcover sharp(pset a, pset b);
/* signature.c */	extern pcover signature(pset_family F1, pset_family D1, pset_family R1);
/* sminterf.c */ extern pset do_sm_minimum_cover(pset_family A);
/* sparse.c */	extern pcover make_sparse(pset_family F, pset_family D, pset_family R);
/* sparse.c */	extern pcover mv_reduce(pset_family F, pset_family D);
/* ucbqsort.c */	extern void qsort(void *, size_t, size_t, int (*) (const void *, const void *));
/* rference: http://www.cplusplus.com/reference/clibrary/cstdlib/qsort.html */
/* void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) ); */
/* The return value of this function should represent whether elem1 is considered less than, equal, or grater than elem2 by returning, respectivelly, a negative value, zero or a positive value. */
/* int compare (const void * a, const void * b)
{
  return ( *(int*)a - *(int*)b );
} */

/* unate.c */	extern pcover map_cover_to_unate(pset *T);
/* unate.c */	extern pcover map_unate_to_cover(pset_family A);
/* unate.c */	extern pset_family exact_minimum_cover(pset_family T);
/* unate.c */	extern pset_family unate_compl(pset_family A);
/* unate.c */	extern pset_family unate_complement(pset_family A);
/* unate.c */	extern pset_family unate_intersect(pset_family A, pset_family B, int largest_only);
/* verify.c */	extern int PLA_permute(pPLA PLA1, pPLA PLA2); /** MM: int na detekciu chyby */
/* verify.c */	extern bool3 PLA_verify(pPLA PLA1, pPLA PLA2);
/* verify.c */	extern bool3 check_consistency(pPLA PLA, FILE* fp);
/* verify.c */	extern bool3 verify(pset_family F, pset_family Fold, pset_family Dold);

#endif // ESPRESSO_MV_H_65464654616146576541656761767
