/*---------------------------------------------------------------*
 *
 * File : solveSigSimple.c
 * Author : NTM
 * Created : 30/09/03
 *
 *
 * 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
 *
 *---------------------------------------------------------------*/

#include <stdlib.h> // free
#include <stdio.h>

#include "types.h"  //MOT
#include "signa.h" // getsigvalue
#include "varia.h" // buildInitialVV, updateVVNegPool, updateVVPosPool
#include "pools.h" // pool

#include "solveSigSimple.h"



/************************************************************************
 ******************* LOCAL FUNCTIONS ************************************
 ************************************************************************/

/////////////// DECLARATIONS ///////////////


//////////////// BODIES ///////////////////


/************************************************************************
 ******************* EXPORTED FUNCTIONS *********************************
 ************************************************************************/

/*
  \brief Given an observation, return: 
  - the deduced VV if the canonical interpretation is 
    coherent (memory is allocated here)
  - NULL otherwise

  This function does not modify the signature; it returns as soon as 
  a conflict is found.<br>
  When examining the signature, it doesn't care whether a pos pool is 
  marked SIG_WEAK or SIG_POS. Similarly, negative pools can be marked 
  SIG_FAINT or SIG_NEG.
  No SIG_XXXCONF allowed however: this should be a non-enriched observation.

  \param tabpool the pools to use
  \param mySig a signature (pos pools should be marked SIG_POS or
  SIG_WEAK; neg pools are SIG_NEG or SIG_FAINT)
  \param n number of variables

*/
MOT* solveSigSimple(MOT* tabpool, signature* mySig, int n)
{
  // VVtab: stores the VV that will be returned.
  // memory is allocated and initialized in buildInitialVV
  MOT* VVtab = buildInitialVV(n,85) ; // initialize VVtab with 01's

  int absPoolNum ;
  int nbPools = mySig->nbPools ;

  /* first deal wit negative pools: */
  for(absPoolNum = 0; absPoolNum < nbPools; absPoolNum++)
      {
	int sigvalue = getsigvalue(mySig, absPoolNum) ;
	if ((sigvalue == SIG_NEG) || (sigvalue == SIG_FAINT))
	  { // this pool is negative, update NegSV
	    MOT* currentPool = pool(tabpool, absPoolNum, n) ;
	    updateVVNegPool(VVtab, currentPool, n);
	  }
	/* immediately test the other values */
	else if ((sigvalue != SIG_POS) && (sigvalue != SIG_WEAK))
	  {
	    fprintf(stderr, "in solveSigSimple: illegal sig value %d\n", sigvalue) ;
	    exit(1) ;
	  }
      }

  /* now try updating with pos pools, and stop as soon as a conflict is detected */
  for(absPoolNum = 0; absPoolNum < nbPools; absPoolNum++)
      {
	int sigvalue = getsigvalue(mySig, absPoolNum) ;
	if ((sigvalue == SIG_POS) || (sigvalue == SIG_WEAK))
	  {
	    MOT* currentPool = pool(tabpool, absPoolNum, n) ;
	    if (updateVVPosPool(VVtab, currentPool, n) == 1)
	      {
		// conflict detected. free VVtab and break
		free(VVtab) ;
		VVtab = NULL ;
		break ;
	      }
	  }
      }

  /* return VVtab (which is NULL if a conflict was detected) */
  return(VVtab) ;
}

