//包de.uni_freiburg.informatik.ultimate.smtinterpol;导入java.math。BigDecimal;导入java.util。排列列表;导入java.util。HashMap;导入java.util。哈希集;导入java.util。地图。进入;导入de.uni_freiburg.informatik.ultimate.logic。注释性术语;导入de.uni_freiburg.informatik.ultimate.logic。ApplicationTerm;导入de.uni_freiburg.informik.ultimate.logic。常数项;导入de.uni_freiburg.informatik.ultimate.logic。FormulaUnLet;导入de.uni_freiburg.informik.ultimate.logic。FunctionSymbol;导入de.uni_freiburg.informatik.ultimate.logic。LetTerm;导入de.uni_freiburg.informatik.ultimate.logic。NoopScript;导入de.uni_freiburg.informatik.ultimate.logic。量化公式;导入de.uni_freiburg.informatik.ultimate.logic。理性;导入de.uni_freiburg.informatik.ultimate.logic。SMTLIB异常;导入de.uni_freiburg.informatik.ultimate.logic。排序;导入de.uni_freiburg.informatik.ultimate.logic。期限;导入de.uni_freiburg.informatik.ultimate.logic。Term变压器;导入de.uni_freiburg.informatik.ultimate.logic。术语变量;导入de.uni_freiburg.informatik.ultimate.logic。理论;导入de.uni_freiburg.informatik.ultimate.logic。理论。求解器设置;导入de.uni_freiburg.informatik.ultimate.smtinterpol.convert。SMTAffineTerm;导入de.uni_freiburg.informatik.ultimate.smtinterpol.interpolate。插值器;导入de.uni_freiburg.informatik.ultimate.smtinterpol.interpolate。插值器。替代者;公共类QuantifierEliminationTQ扩展了NoopScript{理论m_理论;FormulaUnLet m_unletter;布尔m_debug=true;/***当smtlib-script显示(simplify…)时调用此函数*/@覆盖public Term simplifyTerm(Term Term)引发SMTLIBException{m_unletter=新公式UnLet();m_theory=this.getTheory();debug(“#########1###&####启动新的simplify命令###*###_###=###号”);调试(“input:”+term.toStringDirect());哈希图innerMostQuantifiedFormulas=新HashMap();Term termWithPlaceholders=getInnerMost(Term,innerMostQuantifiedFormulas);debug(“最里面的量化公式:”+innerMostQuantifiedFormulas.values());调试(“-------------------”);for(条目entry:innerMostQuantifiedFormulas.entrySet()){QuantifiedFormula qf=(QuantifiedFormula)条目.getValue();debug(“处理子公式:”+qf.toStringDirect());布尔值isForAll=qf.getQuantifier()==量化公式。FORALL公司;断言qf.getVariables().length==1;TermVariable quantifiedVar=qf.getVariables()[0];术语体InNNF=toNNF(isForAll?m_theory.not(qf.getSubformula());debug(“无量词公式的计算NNF:”+bodyInNNF.toStringDirect());术语bodyNoNegationsOrLeq=eliminateNegatedAndLeq(bodyInNNF);debug(“消除否定和大/小相等:”+bodyNoNegationsOrLeq);哈希集extractedTerms=新哈希集();术语bodyIsolatedVar=SMTAffineTerm.cleanup(isolateVarAndExtractTerms(bodyNoNegationsOrLeq,extractedTerms,quantifiedVar));debug(“公式with”+quantifiedVar+“isolated:”+bodyIsolatedVar.toStringDirect());debug(“隔离后从公式中提取以下术语”+quantifiedVar+“:”+extractedTerms);哈希集termSet=computeTermSet(extractedTerms);调试(“S_F:”+术语集);术语结果公式=isForAll?toNNF(m_theory.not(buildFormula(termSet,bodyIsolatedVar,quantifiedVar)),0):构建公式(termSet,bodyIsolatedVar,quantifiedVar);debug(“量词消除的结果:”+resultFormula.toStringDirect());resultFormula=m_unletter.unlet(resultFormal);Term simplifiedResult=makeTrivialSimplifications((ApplicationTerm)resultFormula);debug(“简化结果:”+simplifiedResult.toStringDirect());simplifiedResult=m_unletter.unlet(simplifedResult);termWithPlaceholders=新的替代者(entry.getKey(),simplifiedResult).transform(termWith Placeholders);}调试(“------------------”);debug(“总体结果:”+termWithPlaceholders.toStringDirect());有占位符的回报条款;}void debug(字符串){if(m_debug)(如果(m_debug))System.out.println(“--debug:”+s);}/***提取给定术语中最内层的量化公式,返回一个术语,其中每个公式都被新的TermVariable替换*/private Term getInnerMost(Term Term,HashMap结果){if(QuantifiedFormula&&的术语实例!(((QuantifiedFormula)术语).getSubformula().toString().contains(“exists”)||((QuantifiedFormula)术语).getSubformula().toString().contains(“for all”)){TermVariable t=m_theory.createFreshTermVaiable(“占位符”,m_theology.getBooleanSort());result.put(t,术语);返回t;}else if(QuantifiedFormula的术语实例){QuantifiedFormula qf=(Quantified Formula)项;if(qf.getQuantifier()==0){return m_theory.exists(qf.getVariables(),getInnerMost(qf.getSubformula(),result));}其他{return m_theory.forall(qf.getVariables(),getInnerMost(qf.getSubformula(),result));}}else if(术语AnnotatedTerm的实例){return getInnerMost((AnnotatedTerm)term).getSubterm(),result)//正在丢弃批注。。}else if(术语ApplicationTerm实例){ApplicationTerm at=(ApplicationTerm)term;Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=getInnerMost(位于.getParameters()[i],结果);return m_theory.term(at.getFunction(),newSubterms);}收益期;}/***将无量词公式转换为NNF(步骤1)*/私有Term to NNF(Term Term,int noNots){if(ApplicationTerm的术语实例){ApplicationTerm at=(ApplicationTerm)term;if(等于(m_theory.TRUE))返回noNots%2==0?m理论。正确:m_theory。虚假;else if(at.equals(m_theory.FALSE))返回noNots%2==0?m理论。错误:m_theory。正确;else if(at.getFunction().equals(m_theory.m_Implies)){if(noNots%2==0)return m_theory.or(toNNF(at.getParameters()[0],noNots+1),toNNF;其他的return m_theory.and(toNNF(at.getParameters()[0],noNots+1),toNNF;}else if(at.getFunction().equals(m_theory.m_Not)){如果(noNots==0)返回NNF(位于.getParameters()[0],noNots+1);其他的返回NNF(位于.getParameters()[0],noNots-1);}else if(at.getFunction().equals(m_theory.m_Or)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=toNNF(位于.getParameters()[i],noNots);if(noNots%2==0)return m_theory.term(m_theori.m_Or,newSubterms);其他的return m_theology.term(m_theory.m_And,newSubterms);}else if(at.getFunction().equals(m_theory.m_And)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=toNNF(位于.getParameters()[i],noNots);if(noNots%2==0)return m_theology.term(m_theory.m_And,newSubterms);其他的return m_theory.term(m_theori.m_Or,newSubterms);}else{//过去最内层的布尔函数if(noNots%2==0)收益期;其他的return m_theory.term(m_theori.m_Not,term);}}else if(LetTerm的术语实例){术语unletted=m_unletter.unlett(术语);返回NNF(未注册,无Nots);}收益期;}/***消除负数和大小相等符号(步骤2)*/私有Term eliminateNegatedAndLeq(Term formula){if(ApplicationTerm的公式实例){if(formula.equals(m_theory.TRUE)||formula.equils(m_theory.FALSE))回归公式;ApplicationTerm at=(ApplicationTerm)公式;if(at.getFunction().equals(m_theory.m_And)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=eliminateNegatedAndLeq(at.getParameters()[i]);return m_theory.和(newSubterms);}else if(at.getFunction().equals(m_theory.m_Or)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=eliminateNegatedAndLeq(at.getParameters()[i]);return m_theory.or(newSubterms); }else if(at.getFunction().equals(m_theory.m_Not)){ApplicationTerm negatedAt=(ApplicationTerm)at.getParameters()[0];术语s=negatedAt.getParameters()[0];术语t=negatedAt.getParameters()[1];if(否定At.getFunction().getName()==“=”){返回m_theory.or(m_theory.term(“>”,s,t),m理论术语(“>”,t,s);}else if(negatedAt.getFunction().getName()==“<=”){return m_theory.term(“>”,s,t); }else if(negatedAt.getFunction().getName()==“<”){返回m_theory.or(m_theory.term(“>”,s,t),m理论等于(s,t));}else if(negatedAt.getFunction().getName()==“>=”){return m_theory.term(“>”,t,s); }else if(negatedAt.getFunction().getName()==“>”){返回m_theory.or(m_theory.term(“>”,t,s),m理论等于(t,s));}}else{//应具有非负(in)等式术语s=at.getParameters()[0];术语t=at.getParameters()[1];if(位于.getFunction().getName()==“=”){返回时间:;}否则if(at.getFunction().getName()==“<=”){返回m_theory.or(m_theory.term(“>”,t,s),m理论等于(t,s));}else if(at.getFunction().getName()==“<”){return m_theory.term(“>”,t,s); }else if(at.getFunction().getName()==“>=”){返回m_theory.or(m_theory.term(“>”,s,t),m理论等于(s,t));}else if(at.getFunction().getName()==“>”){return m_theory.term(“>”,s,t); }}} 回归公式;}/***将量化变量放在每一等式的一边(第3步),同时选取另一边的术语*@param公式输入公式*@param extractedTerms当我们隔离量化变量时,我们可以收集“其他”术语并将其写在这里*@param quantifiedVar要隔离的变量*@return隔离quantifiedVar的公式*/专用Term isolateVarAndExtractTerms(Term公式,HashSetextractedTerms,TermVariable quantifiedVar){if(ApplicationTerm的公式实例){ApplicationTerm at=(ApplicationTerm)公式;if(at.getFunction().equals(m_theory.m_And)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=isolateVarAndExtractTerms(at.getParameters()[i],extractedTerms,quantifiedVar);return m_theology.term(m_theory.m_And,newSubterms);}else if(at.getFunction().equals(m_theory.m_Or)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=isolateVarAndExtractTerms(at.getParameters()[i],extractedTerms,quantifiedVar);return m_theory.term(m_theori.m_Or,newSubterms); }else if(at.getFunction().getName()==“>”|| at.getFunction(。getName()=“=”){术语left=at.getParameters()[0];Term right=at.getParameters()[1];SMTAffineTerm affineTermLeft=toAffineTerm(左);SMTAffineTerm affineTermRight=到仿射项(右);//在此处填写://情况是:(functionsymbol affineTermLeft affineTermRight)在{“=”,“>”}中包含functionsymbol//您需要在一侧隔离quantifiedVar(如步骤2所示)//还记得在计算另一边的术语时填写extractedTerms//确保阅读自述文件或相应类中的SMTAffineTerms} }回归公式;}/***将所有部分组合起来,得到返回时无量词的子公式。(步骤4)*/private术语构建公式(哈希集termSet、Term body IsolatedVar、TermVariable quantifiedVariable){数组列表resultFormulas=新ArrayList();//构建左右无限投影resultFormulas.add(buildProjection(bodyIsolatedVar,quantifiedVariable,true));resultFormulas.add(buildProjection(bodyIsolatedVar,quantifiedVariable,false));//构建析取for(术语t:termSet)resultFormulas.add(m_theory.let(quantifiedVariable,t,bodyIsolatedVar));Term[]resultFormulasArray=new Term[resultFormals.size()];resultFormulas.toArray(resultFormulesArray);return m_theory.或(resultFormulasArray);}/***//***构建左侧或右侧的无限投影。*@param公式公式F[x]*@param quantifiedVariable量化变量“x”*@param left true如果我们想要左无限投影false如果我们想要右无限投影*@返回投影公式*/专用术语构建投影(术语公式,TermVariable quantifiedVariable,左边的布尔值){if(ApplicationTerm的公式实例){if(formula.equals(m_theory.TRUE)回归公式;ApplicationTerm at=(ApplicationTerm)公式;if(at.getFunction().equals(m_theory.m_And)){Term[]newSubterms=new Term[at.getParameters().length];for(int i=0;i<at.getParameters().length;i++)newSubterms[i]=buildProjection(位于.getParameters()[i],quantifiedVariable,左侧);return m_theology.term(m_theory.m_And,newSubterms);}else if(at.getFunction().equals(m_theory.m_Or)){Term[]newSubterms=新术语[at.getParameters().length];for(int i=0;i<at.getParameters().length;);i++)newSubterms[i]=buildProjection(位于.getParameters()[i],quantifiedVariable,左侧);return m_theory.term(m_theori.m_Or,newSubterms); }else if(at.getFunction().getName()==“>”){//在此处填写://您有一个术语(>at.getParameters[0]at.getParameters()[1]),您需要//如果标志“left”设置为true/false,则计算左/右无限投影}否则if(at.getFunction().getName()==“=”){返回m_theory。错误;}}else if(LetTerm的公式实例){术语unletted=m_unletter.unlett(公式);return buildProjection(unletted,quantifiedVariable,left);}断言错误//如果我们到达这个位置,公式不仅包含and,or,>=返回null;}/***//***从从公式中提取的一组术语中计算术语集S_F*@param extractedTerms术语集*@return集合S_F(不带+-无穷大)*/私有哈希集computeTermSet(哈希集摘录条款){哈希集result=新哈希集();//在此处填写://公式中有一组项,我们需要计算//它的集合S_F返回结果;}/***尝试通过求解常量上的(in)等式以及“或”s和“和”s与“真”或“假”来简化公式*@param公式要简化的公式*@返回简化等效公式*/私人术语make琐碎简化(术语公式){if(ApplicationTerm的公式实例){ApplicationTerm at=(ApplicationTerm)公式;if(at.equals(m_theory.TRUE)|| at.equals(m_theory.FLUSE))返回时间:;else if(at.getFunction().getName()==“或”|| at.getFunction(。getName()==“and”){布尔值isOr=at.getFunction().getName()==“or”;数组列表trueSubTerms=新排列列表();数组列表falseSubTerms=新ArrayList();数组列表nonTrivialSubTerms=新数组列表();for(术语参数:at.getParameters()){术语简化=makeTrivialSimplifications(param);if(简化等于(m_theory.TRUE))trueSubTerms.add(简化);else if(simplized.equals(m_theory.FALSE))falseSubTerms.add(简体);其他的非平凡子条款.add(简化);}if(isOr){if(!trueSubTerms.isEmpty())返回m_theory。正确;其他{Term[]ntsArray=新Term[nonTrivialSubTerms.size()];nonTrivialSubTerms.toArray(ntsArray);return m_theory.或(ntsArray);}}其他{if(!falseSubTerms.isEmpty())返回m_theory。错误;其他{Term[]ntsArray=新Term[nonTrivialSubTerms.size()];nonTrivialSubTerms.toArray(ntsArray);return m_theory.或(ntsArray);}}}else if(at.getFunction().getName()==“>”){if(at.getParameters()[0]ConstantTerm的实例&&at.get参数()[1]ConstantTerm的实例){SMTAffineTerm s1=SMTAffine Term.create(位于.getParameters()[0]);SMTAffineTerm s2=SMTAffieTerm.create(at.getParameters()[1]);int compResult=(s1.getConstant()).compareTo((s2.getConsant()));if(compResult==1)返回m_theory。正确;其他的返回m_theory。错误;}其他返回时间:;}否则if(at.getFunction().getName()==“=”){if(at.getParameters()[0]ConstantTerm的实例&&at.get参数()[1]ConstantTerm的实例){SMTAffineTerm s1=SMTAffine Term.create(位于.getParameters()[0]);SMTAffineTerm s2=SMTAffieTerm.create(at.getParameters()[1]);int compResult=(s1.getConstant()).compareTo((s2.getConstant()));if(compResult==0)返回m_theory。正确;其他的返回m_theory。错误;}其他返回时间:;}}else if(LetTerm的公式实例){LetTerm lt=(LetTern)公式;术语简化=生成TrivialSimplifications(lt.getSubTerm());if(simplized.equals(m_theory.TRUE)|| simplified.equales(m_ttheory.FALSE))回归简化;其他的回归公式;}回归公式;}/***将线性算术表达式作为项,并返回具有相同值的SMTAffineTerm*/私有SMTAffineTerm到AffineTerms(Term Term){if(ApplicationTerm的术语实例){ApplicationTerm at=(ApplicationTerm)term;if(位于.getFunction().getName()==“+”){SMTAffineTerm结果=SMTAffine Term.create(Rational.ZERO,m_theory.getRealSort());for(术语参数:at.getParameters())result=result.add(toAffineTerm(param));返回结果;}else if(at.getFunction().getName()==“-”){SMTAffineTerm结果=SMTAffine Term.create(Rational.ZERO,m_theory.getRealSort());结果=result.add(toAffineTerm(at.getParameters()[0]));结果=result.add(toAffineTerm(at.getParameters()[1]).negate());返回结果;}else if(at.getFunction().getName()==“*”){SMTAffineTerm recResult1=到附加项(位于.getParameters()[0]);SMTAffineTerm recResult2=到附加项(位于.getParameters()[1]);if(recResult1.isConstant())return recResult2.mul(recResult1.getConstant());else if(recResult2.isConstant())return recResult1.mul(recResult2.getConstant());其他断言错误;}else if(at.getFunction().getName()==“/”){SMTAffineTerm recResult1=toAffineTerm(在.getParameters()[0]处);SMTAffineTerm recResult2=到附加项(位于.getParameters()[1]);断言recResult2.isConstant();return recResult1.div(recResult2.getConstant());}else{//我们有一个常量在.getParameters()处断言。长度==0;return SMTAffineTerm.create(Rational.ONE,at);}}else if(术语ConstantTerm的实例){return SMTAffineTerm.create(term);}else if(TermVariable的术语实例){return SMTAffineTerm.create(Rational.ONE,term);}返回null;}}