#include "DistinctProcessor.hpp"
#include "Lib/Environment.hpp"
#include "Kernel/Formula.hpp"
#include "Kernel/FormulaUnit.hpp"
#include "Kernel/Signature.hpp"
#include "Kernel/Unit.hpp"
#include <cstring>
namespace Shell
{
bool DistinctProcessor::isDistinctPred(Literal* l)
{
const char* n = l->predicateName().c_str();
return n[0]=='$' && memcmp(n+1,"distinct",8)==0;
}
bool DistinctProcessor::apply(FormulaUnit* unit, Unit*& res)
{
Formula* form = unit->formula();
static Stack<unsigned> distConsts;
if(form->connective()==LITERAL) {
Literal* tlLit = form->literal();
if(isDistinctPred(tlLit) && tlLit->isPositive()) {
distConsts.reset();
bool justConsts = true;
Literal::Iterator argIt(tlLit);
while(argIt.hasNext()) {
TermList a = argIt.next();
if(!a.isTerm() || a.term()->arity()!=0) {
justConsts = false;
break;
}
distConsts.push(a.term()->functor());
}
if(justConsts) {
unsigned grpIdx = env.signature->createDistinctGroup(unit);
while(distConsts.isNonEmpty()) {
env.signature->addToDistinctGroup(distConsts.pop(), grpIdx);
}
}else{
USER_ERROR("$distinct should only be used positively with constants");
}
}
}
return false;
}
bool DistinctProcessor::apply(Clause* cl, Unit*& res) {
return false;
}
}