#include "Lib/Environment.hpp"
#include "Kernel/Clause.hpp"
#include "Kernel/Formula.hpp"
#include "Kernel/FormulaUnit.hpp"
#include "Kernel/Problem.hpp"
#include "Kernel/Signature.hpp"
#include "Kernel/TermIterators.hpp"
#include "Kernel/SubformulaIterator.hpp"
#include "GoalGuessing.hpp"
namespace Shell
{
using namespace std;
void GoalGuessing::apply(Problem& prb)
{
_lookInside = env.options->guessTheGoal() != Options::GoalGuess::POSITION;
_checkTop = env.options->guessTheGoal() == Options::GoalGuess::EXISTS_TOP || env.options->guessTheGoal() == Options::GoalGuess::EXISTS_ALL;
_checkSymbols = env.options->guessTheGoal() == Options::GoalGuess::EXISTS_SYM || env.options->guessTheGoal() == Options::GoalGuess::EXISTS_ALL;
_checkPosition = env.options->guessTheGoal() == Options::GoalGuess::POSITION;
if(env.options->guessTheGoal() == Options::GoalGuess::ALL){
_lookInside=true;
_checkSymbols=true;
_checkPosition=true;
}
if(apply(prb.units())) {
prb.invalidateByRemoval();
}
}
bool GoalGuessing::apply(UnitList*& units)
{
bool modified = false;
UnitList::Iterator uit(units);
while(uit.hasNext()) {
Unit* u = uit.next();
if(_checkPosition){
if(u->number() == Unit::getLastParsingNumber()){
u->inference().setInputType(UnitInputType::NEGATED_CONJECTURE);
modified=true;
}
}
if(_lookInside){
if(u->isClause()) {
Clause* cl = static_cast<Clause*>(u);
modified |= apply(cl);
}
else {
FormulaUnit* fu = static_cast<FormulaUnit*>(u);
modified |= apply(fu);
}
}
}
return modified;
}
bool GoalGuessing::apply(Clause* cl)
{
if(cl->isPureTheoryDescendant()){ return false; }
unsigned clen = cl->length();
bool looksLikeGoal = false;
for(unsigned i=0; i<clen; i++) {
Literal* lit = (*cl)[i];
looksLikeGoal |= apply(lit); }
if(looksLikeGoal){ cl->inference().setInputType(UnitInputType::NEGATED_CONJECTURE); }
return looksLikeGoal;
}
bool GoalGuessing::apply(FormulaUnit* fu)
{
bool looksLikeGoal = false;
if(_checkTop && fu->formula()->connective() == EXISTS){
looksLikeGoal = true;
}
if(_checkTop && fu->formula()->connective() == NOT && fu->formula()->uarg()->connective() == FORALL){
looksLikeGoal = true;
}
SubformulaIterator sfit(fu->formula());
while (sfit.hasNext()) {
Formula* sf = sfit.next();
if (sf->connective() == LITERAL){
looksLikeGoal |= apply(sf->literal()); }
}
if(looksLikeGoal){ fu->inference().setInputType(UnitInputType::NEGATED_CONJECTURE); }
return looksLikeGoal;
}
bool GoalGuessing::apply(Literal* lit)
{
if(!_checkSymbols){ return false; }
bool found = false;
TermFunIterator it(lit);
ASS(it.hasNext());
it.next(); while(it.hasNext()){
unsigned f = it.next();
if(f > env.signature->functions()){ continue; }
unsigned unitUsageCnt = env.signature->getFunction(f)->unitUsageCnt();
static unsigned unitUsageCntLimit = env.options->gtgLimit();
if(unitUsageCnt <= unitUsageCntLimit){
env.signature->getFunction(f)->markInGoal();
found = true;
}
}
return found;
}
}