//---------------------------------------------------------------------------

#include "stdafx.h"

using namespace std;

#pragma hdrstop

#include "myExcept.h"
#include "bitvector.h"
#include "SoTerm.h"

//---------------------------------------------------------------------------


SoTerm::SoTerm(void)
{
    dim = -1;
	unwanted = false;
}

SoTerm::SoTerm( const unsigned int iv )
{
	IM.assign(iv, '-');
    dim = iv;
	unwanted = false;
}

SoTerm::~SoTerm(void)
{
}

void SoTerm::clear(void)
{
	IM.clear();
	SO_CoverVector.clear();
	CoverVector.clear();
}

void SoTerm::SetIM( const unsigned int pos, const char val )
{
	if ( pos >= IM.size() ) throw RuntimeException( "SoTerm::SetIM: Index out of range" );
    if ( val != '0' && val != '1' && val != '-' ) throw RuntimeException( "SoTerm::SetIM: Invalid value" );
    if ( dim != -1 && IM[pos] == '-' && val != '-' ) dim--;
    if ( dim != -1 && IM[pos] != '-' && val == '-' ) dim++;
    IM[pos] = val;
}

void SoTerm::SetIM( const string val )
{
	if ( val.size() != IM.size() && IM.size() != 0 ) throw RuntimeException( "SoTerm::SetIM: Wrong IM size" );
	IM = val;
	dim = -1;
}

unsigned int SoTerm::GetDim(void)
// Returns term dimension. If it is not already computed, computes it
{
    unsigned int i, j;

    if ( dim != -1 ) return dim;
    i = 0;
    for ( j = 0; j < IM.size(); j++ )
        if ( IM[j] == '-' ) i++;
    dim = i;
    return i;
}

/*
void SoTerm::DiscardDim()
{
    dim = -1;
}*/

bool SoTerm::Intersects( const string& s ) const
/*
    Returns: do the terms intersect?
*/
{
    unsigned int i;

	if ( s.size() != this->IM.size() ) throw RuntimeException("SoTerm::Intersects: Comparing incompatible terms");
    for ( i = 0; i < IM.size(); i++ )
        if ( this->IM[i] != s[i] && this->IM[i] != '-' && s[i] != '-' ) return false;
    return true;
}

int SoTerm::IntersectSize( const string& s ) const
/*
    Returns the intersection size (dimension)
*/
{
    unsigned int i;
	int j = 0;

	if ( s.size() != this->IM.size() ) throw RuntimeException("SoTerm::Intersects: Comparing incompatible terms");
    for ( i = 0; i < IM.size(); i++ )
        if ( this->IM[i] != s[i] && this->IM[i] != '-' && s[i] != '-' ) return -1;
		else if ( (this->IM[i] == '-' && s[i] != '-') || (this->IM[i] != '-' && s[i] == '-') ) j++;
    return j;
}

bool SoTerm::Contains( const string& s ) const
/*
    Returns: does it contain t?
*/
{
    unsigned int i;

    if ( s.size() != this->IM.size() )
		throw RuntimeException("SoTerm::Contains: Comparing incompatible terms");

    for ( i = 0; i < IM.size(); i++ )
        if ( this->IM[i] != s[i] && this->IM[i] != '-' ) return false;
    return true;
}

SoTerm SoTerm::Intersection( const string& s ) const
/*
    Returns intersection of the terms
    The terms must have an intersection
*/
{
    unsigned int i;
    SoTerm t1;

    t1 = *this;
    for ( i = 0; i < IM.size(); i++ ) {
		if ( t1.IM[i] != s[i] && t1.IM[i] != '-' && s[i] != '-' ) throw RuntimeException( "SoTerm::Intersection: no intersection" );;
        if ( s[i] == '0' || s[i] == '1' ) t1.IM[i] = s[i];
    }
    return t1;
}
