/*----------------------------------------------------------------*
 *
 * File : closure.h
 * Author : NTM
 * Created : 17/11/04
 *
 *
 * Copyright (C) Nicolas Thierry-Mieg, 2006.
 *
 *
 * This file is part of InterPool, written by 
 * Nicolas Thierry-Mieg (CNRS, France) Nicolas.Thierry-Mieg@imag.fr
 *
 * InterPool is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * InterPool 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 InterPool; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *-----------------------------------------------------------------*/
#ifndef _closure_h_
#define _closure_h_

#include "types.h" /* MOT */
#include "signa.h" /* signature, setOfSigs */


/*!
  \file closure.h
  \brief This file holds the closure and setOfClosures 
  definitions and methods.
*/

/******************************************************************
 ****** closure type and low-level primitives
 ******************************************************************/

/*!
  \brief Datatype to store all information relevant to a closure.
*/

/*!
  A closure corresponds to a set of variables. It holds: <br>
  in negPools, the set of neg or faint conflicting pools
  that contain at least one of the vars;<br>
  in posPools, the set of pos or weak conflicting pools
  that contain at least one of the vars;<br>
  negPoolsCost is the cost (ie distance) of the pools in negPools;<br>
  score is (a lower bound of?) what we gain by changing the 
  interpretation of each pool in negPools (doing this makes all
  pools in posPools become non-confflicting). <br>

  structure of xxxPools: <br>
  it is a block of nbMotsPerPoolsVec MOTs, each absolute 
  pool number has a corresponding bit in the block; this bit 
  is 1 iff the pool is conflicting negative (or pos or other) 
  and contains one of the variables for this closure. 
  Any unused bits are set to 0 (padding).
*/
typedef struct
{
  MOT* negPools ; /*!< conflicting neg pools which could be changed */
  MOT* posPools ; /*!< (subset of the?) conflicting pos pools which 
			     would no longer be conflicting */
  int negPoolsCost ; /*!< total cost of the neg and faint pools 
		       in this closure */
  int score ; /*< (lower bound of?) the score of this closure */
} closure ;


/*!
  \brief Build and return a pointer to an empty closure (ie negPools 
  and posPools are empty (NOT NULL!), and negPoolsCost==score==0).
*/
closure* buildEmptyClosure(int nbPools) ;


/*!
  \brief Free all memory relevant to myClosureP. <br>
  We free the vectors, and also the closure area itself: don't try
  accessing or using the closure after this!
*/
void freeClosure(closure* myClosureP) ;


/******************************************************************
 ****** setOfClosures type and low-level primitives
 ******************************************************************/

/*!
  \brief Datatype to represent an arbitrary set of closures.

  This type is useful when the size of the set is not known in advance
  and is likely to grow, shrink, or get shifted around.<br>
  It relies directly on the closure type (it's basically a vector
  of pointers to closure's).
*/
typedef struct
{
  int nbOfClosures; /*!< number of closures in the set */
  closure** allClosuresP; /*!< pointer to the table of closure pointers. 
			      allClosuresP[i] is a pointer to closure i, 
			      for i < nbOfClosures  */
} setOfClosures;


/*!
  \brief Return an empty setOfClosures (mem allocated here).<br>
  content is (O, NULL).
*/
setOfClosures* buildEmptySetOfClosures(void) ;


/*!
  \brief Free all memory in mySetP, including the 
  setOfClosures itself.
*/
void freeSetOfClosures(setOfClosures* mySetP) ;


/*!
  \brief Update *bestClosuresP by possibly emptying it 
  and copying currentClosureP into it, 
  if currentClosureP->score is a current best.<br>
  bestScore is the score of the bestClosuresP closures.<br>
  Returns the new best score.
*/
int updateBestSetOfClosures(closure* currentClosureP, setOfClosures* bestClosuresP,
			    int bestScore, int nbPools) ;


/*!
  \brief Remove any duplicates in *myClosuresP if there are any.
*/
void removeDuplicateClosures(setOfClosures* myClosuresP, int nbPools) ;


/*!
  \brief Given a (non-empty) set of best-scoring closures and 
  an enriched sig, convert the closures to a setOfSigs (which
  are interpretations: they only have SIG_POS or SIG_NEG).
  costOfConfPW is the total cost (ie distance) of all
  conflicting pos or weak pools in enrichedSig.
*/
setOfSigs allClosuresToSigs(setOfClosures* bestClosuresP, int costOfConfPW,
			    signature* enrichedSig) ;


#endif
