#include "stdafx.h"
#include "Impl.h"
#include "Separator.h"
#include "func.h"

//#include <iostream>
#include <sstream>

Impl::Impl(BM Num, bool Indep, BM P)
{
	Num &= ~P;
	this->Num = Num;
	this->Indep = Indep;
	this->P = P;
	this->Pw = false;

	this->Ind = count(Num);
}

bool Impl::getVal(BM Num) const
{
	return !((Num ^ this->Num) & ~this->P);
}


Impl* Impl::tryGlue(Impl &a)
{
	if (this->P != a.P)
		return 0;
	BM d = this->Num ^ a.Num;
	if (!isPow2(d))
		return 0;
	this->Pw = true;
	a.Pw = true;
//	std::cout << "( " << a.Num << " + "<< this->Num << " ) & " << a.P << " -> " << (this->Num & a.Num )<< " & " <<( this->P | d) <<std::endl;
	return new Impl(this->Num & a.Num, false, this->P | d);
}

bool Impl::operator==(const Impl &a) const
{
	return (this->Num == a.Num && this->P == a.P);
}

void Impl::ClrFlg( void )
{
	this->Pw = false;
}

Impl::~Impl(void)
{
}

bool compIndex(const Impl *a, const Impl *b)
{
	int d;
	d = a->Ind - b->Ind;
	if (d)
		return d<0;
	d = a->Num - b->Num;
	if (d)
		return d<0;
	d = a->P - b->P;
	return d<0;
}

bool ImplEqual(const Impl *a, const Impl *b)
{
	return (*a) == (*b);
}

std::string Impl::toString( int Nv ) const
{
	std::ostringstream r;
	Separator sep("*");
	if (this->P == ((1<<Nv)-1))
		return "1";
	Nv--;
	for (BM Num = this->Num, P = this->P;
		 Nv >= 0;
		 Nv--, Num >>= 1, P >>= 1)
	{
		if (P&1)
			continue;
		bool Inv = !(Num & 1);
		r << sep();
		if (Inv)
			r << "NOT(" << "X_" << Nv << ")";
		else
			r << "X_" << Nv;
	}
	return r.str();
}
