ASTForm* DistributiveAntiPrenexer::universalDistributiveAntiPrenex(ASTForm *form) { static_assert(std::is_base_of<ASTForm_q, ForallClass>::value, "ForallClass is not derived from 'ASTForm_q' class"); // First call the anti-prenexing rule to push the quantifier as deep as possible //ASTForm* antiPrenexedForm = universalAntiPrenex<ForallClass>(form); // Push negations down as well NegationUnfolder negationUnfolding; ASTForm* antiPrenexedForm = reinterpret_cast<ASTForm*>(form->accept(negationUnfolding)); if(antiPrenexedForm->kind == aAll1 || antiPrenexedForm->kind == aAll2) { // Not everything was pushed, we can try to call the distribution ForallClass* allForm = reinterpret_cast<ForallClass*>(antiPrenexedForm); switch(allForm->f->kind) { case aOr: return distributeConjunction<ForallClass>(allForm); case aAnd: return distributiveRule<ForallClass, ASTForm_And>(allForm); default: UniversalQuantifierRemover universalRemover; antiPrenexedForm = reinterpret_cast<ASTForm*>(antiPrenexedForm->accept(universalRemover)); return reinterpret_cast<ASTForm*>(antiPrenexedForm->accept(negationUnfolding)); } } else { // We are done return antiPrenexedForm; } }
ASTForm* FullAntiPrenexer::nonDistributiveRule(QuantifierClass *qForm) { static_assert(std::is_base_of<ASTForm_q, QuantifierClass>::value, "QuantifierClass is not derived from 'ASTForm_q' class"); static_assert(std::is_base_of<ASTForm_ff, BinopClass>::value, "BinopClass is not derived from 'ASTForm_ff' class"); // Ex . f1 op f2 -> (Ex X. f1) op f2 // Ex . f2 op f2 -> f1 op (Ex X. f2) BinopClass *binopForm = static_cast<BinopClass*>(qForm->f); ASTForm *tempResult; IdentList *bound = qForm->vl; IdentList left, right, middle; IdentList free1, bound1; IdentList free2, bound2; binopForm->f1->freeVars(&free1, &bound1); binopForm->f2->freeVars(&free2, &bound2); for (auto var = bound->begin(); var != bound->end(); ++var) { bool varInLeft = free1.exists(*var); bool varInRight = free2.exists(*var); // Ex var. f1 op f2 | var in f1 && var in f2 if (varInLeft && varInRight) { middle.push_back(*var); // (Ex var. f1) op f2 | var notin f2 } else if(varInLeft) { left.push_back(*var); // f1 op (Ex var. f2) | var notin f1 } else if(varInRight) { right.push_back(*var); } // f1 op f2 | var notin f1 && var notin f2 } qForm->f = nullptr; delete qForm; if(!left.empty()) { tempResult = new QuantifierClass(nullptr, new IdentList(left), binopForm->f1, binopForm->f1->pos); binopForm->f1 = static_cast<ASTForm*>(tempResult->accept(*this)); } if(!right.empty()) { tempResult = new QuantifierClass(nullptr, new IdentList(right), binopForm->f2, binopForm->f2->pos); binopForm->f2 = static_cast<ASTForm*>(tempResult->accept(*this)); } if(!middle.empty()) { tempResult = new QuantifierClass(nullptr, new IdentList(middle), binopForm, binopForm->pos); return tempResult; } else { return binopForm; } }
ASTForm* DistributiveAntiPrenexer::existentialDistributiveAntiPrenex(ASTForm *form) { static_assert(std::is_base_of<ASTForm_q, ExistClass>::value, "ExistClass is not derived from 'ASTForm_q' class"); // First call the anti-prenexing rule to push the quantifier as deep as possible //ASTForm* antiPrenexedForm = existentialAntiPrenex<ExistClass>(form); // Expand Universal Quantifier UniversalQuantifierRemover universalUnfolding; ASTForm* antiPrenexedForm = reinterpret_cast<ASTForm*>(form->accept(universalUnfolding)); // Push negations down as well NegationUnfolder negationUnfolding; antiPrenexedForm = reinterpret_cast<ASTForm*>(antiPrenexedForm->accept(negationUnfolding)); if(antiPrenexedForm->kind == aEx1 || antiPrenexedForm->kind == aEx2) { ExistClass* exForm = reinterpret_cast<ExistClass*>(antiPrenexedForm); switch(exForm->f->kind) { case aOr: return distributiveRule<ExistClass, ASTForm_Or>(exForm); case aAnd: return distributeDisjunction<ExistClass>(exForm); default: return antiPrenexedForm; } } else { // We are done return antiPrenexedForm; } }
/** * Unfolds the called macro by substituting its formal parameters with real * parameters * * @param called: called macro * @param realParams: real parameters * @return: unfolded formula */ ASTForm* unfoldFormula(PredLibEntry* called, ASTList* realParams) { IdentList* formalParams = called->formals; ASTForm* clonnedFormula = (called->ast)->clone(); ASTForm* unfoldedFormula = clonnedFormula->unfoldMacro(formalParams, realParams); Flattener f_visitor; return static_cast<ASTForm*>(unfoldedFormula->accept(f_visitor)); }