#ifndef __FiniteModelMultiSorted__
#define __FiniteModelMultiSorted__
#include "Lib/DHMap.hpp"
#include "Kernel/Unit.hpp"
#include "Kernel/Term.hpp"
namespace FMB {
using namespace Lib;
using namespace Kernel;
class FiniteModelMultiSorted {
DArray<unsigned> _sizes;
static const char INTP_UNDEF = 0;
static const char INTP_FALSE = 1;
static const char INTP_TRUE = 2;
DArray<unsigned> _f_offsets;
DArray<unsigned> _p_offsets;
DArray<unsigned> _f_interpretation;
DArray<char> _p_interpretation;
DArray<DArray<int>> sortRepr;
void initTables();
unsigned args2var(const DArray<unsigned>& args, const DArray<unsigned>& sizes,
const DArray<unsigned>& offsets, unsigned s, OperatorType* sig)
{
unsigned var = offsets[s];
unsigned mult = 1;
for(unsigned i=0;i<args.size();i++){
var += mult*(args[i]-1);
unsigned s = sig->arg(i).term()->functor();
mult *=sizes[s];
}
return var;
}
public:
FiniteModelMultiSorted(DArray<unsigned> sortSizes) : _sizes(std::move(sortSizes)) {
initTables();
}
void addFunctionDefinition(unsigned f, const DArray<unsigned>& args, unsigned res);
void addPredicateDefinition(unsigned f, const DArray<unsigned>& args, bool res);
bool evaluate(Unit* unit, bool expectingPartial = false);
unsigned evaluateGroundTerm(Term* term);
bool evaluateGroundLiteral(Literal* literal);
void eliminateSortFunctionsAndPredicates(const Stack<unsigned>& sortFunctions, const Stack<unsigned>& sortPredicates);
void restoreEliminatedDefinitions(Kernel::Problem* prob);
std::string toString();
private:
unsigned evaluateTerm(TermList, const DHMap<unsigned,unsigned>& subst);
bool evaluateLiteral(Literal*, const DHMap<unsigned,unsigned>& subst);
bool evaluateFormula(Formula*, DHMap<unsigned,unsigned>& subst);
Set<unsigned> _implicitlyEliminatedFunctions;
Set<unsigned> _implicitlyEliminatedPredicates;
void restoreEliminatedFunDef(Problem::FunDef*);
void restoreImplicitlyEliminatedFun(unsigned f);
void restoreEliminatedPredDef(Problem::PredDef*);
void restoreImplicitlyEliminatedPred(unsigned p);
void restoreGlobalPredicateFlip(Problem::GlobalFlip*);
void restoreViaCondFlip(Problem::CondFlip*);
Formula* partialEvaluate(Formula* formula);
bool evaluateOld(Formula* formula,unsigned depth=0);
DHMap<std::pair<unsigned,unsigned>,Term*> _domainConstants;
DHMap<Term*,std::pair<unsigned,unsigned>> _domainConstantsRev;
public:
Term* getDomainConstant(unsigned c, unsigned srt)
{
Term* t;
std::pair<unsigned,unsigned> pair = std::make_pair(c,srt);
if(_domainConstants.find(pair,t)) return t;
std::string name = "domCon_"+env.signature->typeConName(srt)+"_"+Lib::Int::toString(c);
unsigned f = env.signature->addFreshFunction(0,name.c_str());
TermList srtT = TermList(AtomicSort::createConstant(srt));
env.signature->getFunction(f)->setType(OperatorType::getConstantsType(srtT));
t = Term::createConstant(f);
_domainConstants.insert(pair,t);
_domainConstantsRev.insert(t,pair);
return t;
}
std::pair<unsigned,unsigned> getDomainConstant(Term* t)
{
std::pair<unsigned,unsigned> pair;
if(_domainConstantsRev.find(t,pair)) return pair;
USER_ERROR("Evaluated to "+t->toString()+" when expected a domain constant, probably a partial model");
}
bool isDomainConstant(Term* t)
{
return _domainConstantsRev.find(t);
}
std::string prepend(const char* prefix, std::string name) {
if (name.empty()) {
return std::string(prefix);
} else if(name[0] == '$') {
return std::string("'") + prefix + name + "'";
} else if (name[0] == '\'') {
std::string dequoted = name.substr(1, name.length() - 1);
return std::string("'") + prefix + dequoted;
} else {
return prefix + name;
}
}
std::string append(std::string name, const char* suffix) {
if (name.empty()) {
return std::string(suffix);
} else if(name[0] == '$') {
return std::string("'") + name + suffix + "'";
} else if (name[0] == '\'') {
std::string dequoted = name.substr(0, name.length() - 1);
return dequoted + suffix + "'";
} else {
return name + suffix;
}
}
};
} #endif