void Signature::make(IdentList &idents) { size = idents.size(); int *tab1 = new int[size]; int *tab2 = new int[size]; IdentList::iterator i; unsigned int x,y,s; for (i = idents.begin(), x = 0; i != idents.end(); i++, x++) tab1[x] = tab2[x] = offsets.off(*i); qsort((int *) tab2, size, sizeof(int), sortcmp); sign = new int[size]; hashvalue = 0; for (x = 0; x < size; x++) { for (y = 0, s = 0; tab2[y] != tab1[x]; y++) if (y < size && tab2[y] != tab2[y+1]) s++; sign[x] = s; hashvalue = hashvalue*x+sign[x]; } delete[] tab1; delete[] tab2; }
IdentList* intersection(IdentList *i1, IdentList *i2) // make sorted intersection of sorted identlists { if (!i1 || !i2) return NULL; IdentList *r = new IdentList; Ident *id1 = i1->begin(); Ident *id2 = i2->begin(); while (id1 != i1->end() && id2 != i2->end()) { if (*id1 < *id2) id1++; else if (*id1 > *id2) id2++; else { r->push_back(*id1); id1++; id2++; } } if (r->empty()) { delete r; r = NULL; } return r; }
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; } }
IdentList * subst(IdentList *i1, IdentList *i2, IdentList *i3, Ident except) { // map i1 using i2->i3 (but leave 'except' unchanged) invariant(i1 && i2 && i3 && i2->size() == i3->size()); IdentList *res = new IdentList; for (IdentList::iterator j1 = i1->begin(); j1 != i1->end(); j1++) if (*j1 == except) res->push_back(*j1); else res->push_back(subst(*j1, i2, i3)); return res; }
/** * Adds constraints for first-order variables to be singletons, i.e. contain * only one element * * @return: restricted formula */ ASTForm* ASTForm::restrictFormula() { ASTForm* restrictedFormula = this; // For all used first-order variables FirstOrder(x) is appended to formulae IdentList free, bound; ASTForm_FirstOrder* singleton; this->freeVars(&free, &bound); IdentList *allVars = ident_union(&free, &bound); if (allVars != 0) { Ident* it = allVars->begin(); while(it != allVars->end()) { // only variables that are not already singletoned are appended to formula if (symbolTable.lookupType(*it) == Varname1) { singleton = new ASTForm_FirstOrder(new ASTTerm1_Var1((*it), Pos()), Pos()); restrictedFormula = new ASTForm_And(singleton, restrictedFormula, Pos()); } ++it; } } return restrictedFormula; }
IdentList* ident_union(IdentList *i1, IdentList *i2) // merge sorted identlists into union { if ((!i1 || i1->empty()) && (!i2 || i2->empty())) return NULL; if (!i1) return new IdentList(*i2); if (!i2) return new IdentList(*i1); IdentList *r = new IdentList; Ident *id1 = i1->begin(); Ident *id2 = i2->begin(); while (id1 != i1->end() && id2 != i2->end()) { if (*id1 < *id2) { r->push_back(*id1); id1++; } else if (*id1 > *id2) { r->push_back(*id2); id2++; } else { r->push_back(*id1); id1++; id2++; } } while (id1 != i1->end()) { r->push_back(*id1); id1++; } while (id2 != i2->end()) { r->push_back(*id2); id2++; } return r; }
void MonaUntypedAST::makeGTAGuide() { IdentList *univs = symbolTable.allUnivs(); if (numTypes > 0) { // convert types to guide if (!univs || univs->empty()) { cout << "Error: Types declared but no universes (or trees)\n" << "Execution aborted\n"; exit(-1); } if (univs->size() == 1) { // boolean and universe state space must be different Name name = Name("<dummy>", dummyPos); symbolTable.insertUniv(&name, NULL, true); delete univs; univs = symbolTable.allUnivs(); } guide_declaration = new Guide_Declaration(new GuideFuncList, dummyPos); typedUnivs2guide(univs->size(), univs, 0, ""); } if (guide_declaration) { // guide is declared /*#warning NOT REQUIRING UNIVERSES*/ /* if (!univs || univs->empty()) { cout << "Error: Guide declared but no universes\n" << "Execution aborted\n"; exit(-1); } */ // fill tables unsigned numUnivs = univs->size(); char **univPos = (char **) mem_alloc(sizeof(char *)*numUnivs); char **univName = (char **) mem_alloc(sizeof(char *)*numUnivs); IdentList::iterator id; int i; for (id = univs->begin(), i = 0; id != univs->end(); id++, i++) { univName[i] = symbolTable.lookupSymbol(*id); univPos[i] = symbolTable.lookupPos(*id); } unsigned numSs = guide_declaration->funcList->size(); SsId *muLeft = (SsId *) mem_alloc(sizeof(SsId)*numSs); SsId *muRight = (SsId *) mem_alloc(sizeof(SsId)*numSs); char **ssName = (char **) mem_alloc(sizeof(char *)*numSs); SsKind *ssKind = 0; int *ssType = 0; if (numTypes > 0) { ssKind = (SsKind *) mem_alloc(sizeof(SsKind)*numSs); ssType = (int *) mem_alloc(sizeof(int)*numSs); } GuideFuncList::iterator g; for (g = guide_declaration->funcList->begin(), i = 0; g != guide_declaration->funcList->end(); g++, i++) { muLeft[i] = symbolTable.lookupNumber((*g)->name2); muRight[i] = symbolTable.lookupNumber((*g)->name3); ssName[i] = (*g)->name1->str; if (numTypes > 0) { switch((*g)->kind) { case SS_UNIVHAT: ssKind[i] = gtaSSUNIVHAT; break; case SS_ORHAT: ssKind[i] = gtaSSORHAT; break; case SS_ORLEAF: ssKind[i] = gtaSSORLEAF; break; case SS_AND: ssKind[i] = gtaSSAND; break; case SS_DUMMY: ssKind[i] = gtaSSDUMMY; break; default: ; } Ident sstype = symbolTable.lookupSSType(symbolTable.lookupIdent((*g)->name1)); if (sstype != -1) { char *sstypename = symbolTable.lookupSymbol(sstype); int j; for (j = 0; j < numTypes; j++) if (treetypes[j].name == sstypename) { ssType[i] = j; break; } invariant(j < numTypes); } else ssType[i] = -1; } } makeGuide(numSs, muLeft, muRight, ssName, numUnivs, univPos, univName, ssType, ssKind); if (!checkDisjoint()) { cout << "Illegal guide and universe declarations:\n" << "Universes must have disjoint state spaces\n" << "Execution aborted\n"; exit(-1); } if (!checkAllUsed()) { cout << "Illegal guide and universe declarations:\n" << "All state spaces must be reachable\n" << "Execution aborted\n"; exit(-1); } if (!checkAllCovered()) { cout << "Illegal guide and universe declarations:\n" << "Every infinite path in the guide must belong to a universe\n" << "Execution aborted\n"; exit(-1); } } else { // no guide declared, make default if (!univs || univs->empty()) { // make one universe Name name = Name("<univ>", dummyPos); symbolTable.insertUniv(&name, (char *) NULL); delete univs; univs = symbolTable.allUnivs(); } if (univs->size() == 1) { // boolean and universe state space must be different Name name = Name("<dummy>", dummyPos); symbolTable.insertUniv(&name, NULL, true); delete univs; univs = symbolTable.allUnivs(); } // fill name table unsigned numUnivs = univs->size(); char **univName = (char **) mem_alloc(sizeof(char *)*numUnivs); Ident *id; int u; for (id = univs->begin(), u = 0; id != univs->end(); id++, u++) univName[u] = symbolTable.lookupSymbol(*id); makeDefaultGuide(numUnivs, univName); } delete univs; }
int main(int argc, char *argv[]) { std::set_new_handler(&mem_error); if (!ParseArguments(argc, argv)) { Usage(); exit(-1); } // Disable core dump struct rlimit r_core; r_core.rlim_cur = 0; r_core.rlim_max = 0; setrlimit(RLIMIT_CORE, &r_core); // Set demo limits if (options.demo) { struct rlimit r_cpu, r_as; memlimit = true; r_cpu.rlim_cur = 30; // max 30 secs. r_cpu.rlim_max = 30; setrlimit(RLIMIT_CPU, &r_cpu); r_as.rlim_cur = 20971520; // max 20MB r_as.rlim_max = 20971520; setrlimit(RLIMIT_DATA, &r_as); signal(SIGXCPU, &cpuLimit); } initTimer(); Timer timer_total; timer_total.start(); ///////// PARSING //////////////////////////////////////////////////////// if (options.printProgress) cout << "MONA v" << VERSION << "-" << RELEASE << " for WS1S/WS2S\n" "Copyright (C) 1997-2008 BRICS\n\n" "PARSING\n"; Timer timer_parsing; timer_parsing.start(); loadFile(inputFileName); yyparse(); MonaAST *ast = untypedAST->typeCheck(); lastPosVar = ast->lastPosVar; allPosVar = ast->allPosVar; timer_parsing.stop(); if (options.printProgress) { cout << "Time: "; timer_parsing.print(); } delete untypedAST; if (options.dump) { // Dump AST for main formula, verify formulas, and assertion cout << "Main formula:\n"; (ast->formula)->dump(); Deque<ASTForm *>::iterator vf; Deque<char *>::iterator vt; for (vf = ast->verifyformlist.begin(), vt = ast->verifytitlelist.begin(); vf != ast->verifyformlist.end(); vf++, vt++) { cout << "\n\nFormula " << *vt << ":\n"; (*vf)->dump(); } cout << "\n\nAssertions:\n"; (ast->assertion)->dump(); cout << "\n"; if (lastPosVar != -1) cout << "\nLastPos variable: " << symbolTable.lookupSymbol(lastPosVar) << "\n"; if (allPosVar != -1) cout << "\nAllPos variable: " << symbolTable.lookupSymbol(allPosVar) << "\n"; // Dump ASTs for predicates and macros PredLibEntry *pred = predicateLib.first(); while (pred != NULL) { if (pred->isMacro) cout << "\nMacro '"; else cout << "\nPredicate '"; cout << symbolTable.lookupSymbol(pred->name) << "':\n"; (pred->ast)->dump(); cout << "\n"; pred = predicateLib.next(); } // Dump restrictions if (symbolTable.defaultRestriction1) { cout << "\nDefault first-order restriction (" << symbolTable.lookupSymbol(symbolTable.defaultIdent1) << "):\n"; symbolTable.defaultRestriction1->dump(); cout << "\n"; } if (symbolTable.defaultRestriction2) { cout << "\nDefault second-order restriction (" << symbolTable.lookupSymbol(symbolTable.defaultIdent2) << "):\n"; symbolTable.defaultRestriction2->dump(); cout << "\n"; } Ident id; for (id = 0; id < (Ident) symbolTable.noIdents; id++) { Ident t; ASTForm *f = symbolTable.getRestriction(id, &t); if (f) { cout << "\nRestriction for #" << id << " (" << symbolTable.lookupSymbol(id) << "):"; if (t != -1) cout << " default\n"; else { cout << "\n"; f->dump(); cout << "\n"; } } } } if (options.mode != TREE && (options.graphvizSatisfyingEx || options.graphvizCounterEx || options.inheritedAcceptance)) cout << "Warning: options -gc, -gs, and -h are only used in tree mode\n"; if (options.mode == TREE && options.graphvizDFA) cout << "Warning: option -gw is only used in linear mode\n"; if (options.mode == TREE && (options.dump || options.whole) && !options.externalWhole) printGuide(); ///////// CODE GENERATION //////////////////////////////////////////////// if (options.printProgress) cout << "\nCODE GENERATION\n"; Timer timer_gencode; timer_gencode.start(); // Generate code codeTable = new CodeTable; VarCode formulaCode = ast->formula->makeCode(); VarCode assertionCode = ast->assertion->makeCode(); Deque<VarCode> verifyCode; /* #warning NEW: 'VERIFY' */ for (Deque<ASTForm *>::iterator i = ast->verifyformlist.begin(); i != ast->verifyformlist.end(); i++) verifyCode.push_back((*i)->makeCode()); // Implicitly assert restrictions for all global variables for (IdentList::iterator i = ast->globals.begin(); i != ast->globals.end(); i++) assertionCode = andList(assertionCode, getRestriction(*i, NULL)); // Restrict assertion if not trivial if (assertionCode.code->kind != cTrue) assertionCode = codeTable->insert (new Code_Restrict(assertionCode, assertionCode.code->pos)); // Add assertion to main formula and to all verify formulas for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) { assertionCode.code->refs++; *i = andList(*i, VarCode(copy(assertionCode.vars), assertionCode.code)); } formulaCode = andList(formulaCode, assertionCode); timer_gencode.stop(); if (options.printProgress) { codeTable->print_statistics(); /* if (options.dump && options.statistics) codeTable->print_sizes(); */ cout << "Time: "; timer_gencode.print(); } ///////// REORDER BDD OFFSETS //////////////////////////////////////////// if (options.reorder >= 1) { Timer timer_reorder; timer_reorder.start(); if (options.printProgress) cout << "\nREORDERING\n"; // reorder using heuristics offsets.reorder(); // regenerate DAG in new codetable CodeTable *oldCodeTable = codeTable, *newCodeTable = new CodeTable; IdentList emptylist; codeTable = newCodeTable; regenerate = true; // force making new nodes VarCode newcode = formulaCode.substCopy(&emptylist, &emptylist); Deque<VarCode> newverifycode; for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) newverifycode.push_back((*i).substCopy(&emptylist, &emptylist)); codeTable->clearSCTable(); regenerate = false; codeTable = oldCodeTable; formulaCode.remove(); for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) (*i).remove(); formulaCode = newcode; verifyCode.reset(); for (Deque<VarCode>::iterator i = newverifycode.begin(); i != newverifycode.end(); i++) verifyCode.push_back(*i); delete oldCodeTable; codeTable = newCodeTable; if (options.printProgress) { codeTable->print_statistics2(); cout << "Time: "; timer_reorder.print(); } } ///////// REDUCTION AND CODE DUMPING ///////////////////////////////////// if (options.optimize >= 1) { if (options.printProgress) cout << "\nREDUCTION\n"; Timer timer_reduction; timer_reduction.start(); // Reduce formulaCode.reduceAll(&verifyCode); timer_reduction.stop(); if (options.printProgress) { codeTable->print_reduction_statistics(); /* if (options.dump && options.statistics) codeTable->print_sizes(); */ cout << "Time: "; timer_reduction.print(); } } if (options.dump) { // Dump symboltable symbolTable.dump(); // Dump code cout << "\nMain formula:\n"; formulaCode.dump(); cout << "\n\n"; Deque<VarCode>::iterator i; Deque<char *>::iterator j; for (i = verifyCode.begin(), j = ast->verifytitlelist.begin(); i != verifyCode.end(); i++, j++) { cout << "Formula " << *j << ":\n"; (*i).dump(); cout << "\n\n"; } } if (options.graphvizDAG) { printf("digraph MONA_CODE_DAG {\n" " size = \"7.5,10.5\";\n" " main [shape = plaintext];\n" " main -> L%lx;\n", (unsigned long) formulaCode.code); formulaCode.code->viz(); Deque<VarCode>::iterator i; Deque<char *>::iterator j; for (i = verifyCode.begin(), j = ast->verifytitlelist.begin(); i != verifyCode.end(); i++, j++) { printf(" \"%s\" [shape = plaintext];\n" " \"%s\" -> L%lx;\n", *j, *j, (unsigned long) (*i).code); (*i).code->viz(); } formulaCode.unmark(); for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) (*i).unmark(); cout << "}\n"; } ///////// AUTOMATON CONSTRUCTION ///////////////////////////////////////// // Make variable lists Deque<char *> *verifytitlelist = ast->verifytitlelist.copy(); if (lastPosVar != -1) ast->globals.remove(lastPosVar); if (allPosVar != -1) ast->globals.remove(allPosVar); ast->globals.sort(); // sort by id (= index) int numVars = ast->globals.size(); int ix = 0; char **vnames = new char*[numVars]; unsigned *offs = new unsigned[numVars]; char *types = new char[numVars]; int **univs = new int*[numVars]; int *trees = new int[numVars]; SSSet *statespaces = new SSSet[numVars]; IdentList sign, freeVars; IdentList::iterator id; for (id = ast->globals.begin(); id != ast->globals.end(); id++, ix++) { statespaces[ix] = stateSpaces(*id); vnames[ix] = symbolTable.lookupSymbol(*id); offs[ix] = offsets.off(*id); sign.push_back(ix); freeVars.push_back(*id); switch (symbolTable.lookupType(*id)) { case VarnameTree: trees[ix] = 1; break; default: trees[ix] = 0; } IdentList *uu = symbolTable.lookupUnivs(*id); if (uu) { unsigned j; univs[ix] = new int[uu->size()+1]; for (j = 0; j < uu->size(); j++) univs[ix][j] = symbolTable.lookupUnivNumber(uu->get(j)); univs[ix][j] = -1; } else univs[ix] = 0; switch (symbolTable.lookupType(*id)) { case Varname0: types[ix] = 0; break; case Varname1: types[ix] = 1; break; default: types[ix] = 2; break; } } if (options.printProgress) cout << "\nAUTOMATON CONSTRUCTION\n"; Timer timer_automaton; timer_automaton.start(); DFA *dfa = 0; Deque<DFA *> dfalist; GTA *gta = 0; Deque<GTA *> gtalist; // Initialize bdd_init(); codeTable->init_print_progress(); if (options.mode != TREE) { // Generate DFAs dfa = formulaCode.DFATranslate(); if (lastPosVar != -1) dfa = st_dfa_lastpos(dfa, lastPosVar); if (allPosVar != -1) dfa = st_dfa_allpos(dfa, allPosVar); for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) { DFA *d = (*i).DFATranslate(); if (lastPosVar != -1) d = st_dfa_lastpos(d, lastPosVar); if (allPosVar != -1) d = st_dfa_allpos(d, allPosVar); dfalist.push_back(d); } } else { // Generate GTAs gta = formulaCode.GTATranslate(); if (allPosVar != -1) gta = st_gta_allpos(gta, allPosVar); for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) { GTA *g = (*i).GTATranslate(); if (allPosVar != -1) g = st_gta_allpos(g, allPosVar); gtalist.push_back(g); } } formulaCode.remove(); for (Deque<VarCode>::iterator i = verifyCode.begin(); i != verifyCode.end(); i++) (*i).remove(); timer_automaton.stop(); if (options.printProgress) { if (options.statistics) cout << "Total automaton construction time: "; else cout << "Time: "; timer_automaton.print(); } delete ast; delete codeTable; ///////// PRINT AUTOMATON //////////////////////////////////////////////// DFA *dfa2 = dfa; GTA *gta2 = gta; Deque<DFA *> *dfalist2 = &dfalist; Deque<GTA *> *gtalist2 = >alist; if (options.whole && !options.externalWhole) cout << "\n"; if (options.unrestrict) { // Unrestrict automata if (options.mode != TREE) { DFA *t = dfaCopy(dfa2); dfaUnrestrict(t); dfa2 = dfaMinimize(t); dfaFree(t); dfalist2 = new Deque<DFA *>; for (Deque<DFA *>::iterator i = dfalist.begin(); i != dfalist.end(); i++) { t = dfaCopy(*i); dfaUnrestrict(t); dfalist2->push_back(dfaMinimize(t)); dfaFree(t); } } else { GTA *t = gtaCopy(gta2); gtaUnrestrict(t); gta2 = gtaMinimize(t); gtaFree(t); gtalist2 = new Deque<GTA *>; for (Deque<GTA *>::iterator i = gtalist.begin(); i != gtalist.end(); i++) { t = gtaCopy(*i); gtaUnrestrict(t); gtalist2->push_back(gtaMinimize(t)); gtaFree(t); } } } if (options.whole) // Print whole automaton if (options.mode != TREE) { if (options.externalWhole) { if (!dfalist.empty()) cout << "Main formula:\n"; DFA *t = dfaCopy(dfa2); st_dfa_replace_indices(t, &sign, &freeVars, false, true); dfaExport(t, 0, numVars, vnames, types); dfaFree(t); Deque<DFA *>::iterator i; Deque<char *>::iterator j; for (i = dfalist2->begin(), j = verifytitlelist->begin(); i != dfalist2->end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; t = dfaCopy(*i); st_dfa_replace_indices(t, &sign, &freeVars, false, true); dfaExport(t, 0, numVars, vnames, types); dfaFree(t); } } else if (options.graphvizDFA) { dfaPrintGraphviz(dfa2, numVars, offs); for (Deque<DFA *>::iterator i = dfalist2->begin(); i != dfalist2->end(); i++) dfaPrintGraphviz(*i, numVars, offs); } else { if (!dfalist.empty()) cout << "Main formula:\n"; dfaPrint(dfa2, numVars, vnames, offs); Deque<DFA *>::iterator i; Deque<char *>::iterator j; for (i = dfalist2->begin(), j = verifytitlelist->begin(); i != dfalist2->end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; dfaPrint(*i, numVars, vnames, offs); } } } else { if (options.externalWhole) { if (!gtalist.empty()) cout << "Main formula:\n"; GTA *t = gtaCopy(gta2); st_gta_replace_indices(t, &sign, &freeVars, false, true); gtaExport(t, 0, numVars, vnames, types, statespaces, options.inheritedAcceptance); gtaFree(t); Deque<GTA *>::iterator i; Deque<char *>::iterator j; for (i = gtalist2->begin(), j = verifytitlelist->begin(); i != gtalist2->end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; t = gtaCopy(*i); st_gta_replace_indices(t, &sign, &freeVars, false, true); gtaExport(t, 0, numVars, vnames, types, statespaces, options.inheritedAcceptance); gtaFree(t); } } else { if (!gtalist.empty()) cout << "Main formula:\n"; gtaPrint(gta2, offs, numVars, vnames, options.inheritedAcceptance); Deque<GTA *>::iterator i; Deque<char *>::iterator j; for (i = gtalist2->begin(), j = verifytitlelist->begin(); i != gtalist2->end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; gtaPrint(*i, offs, numVars, vnames, options.inheritedAcceptance); } } } else if (options.analysis && !options.graphvizSatisfyingEx && !options.graphvizCounterEx && options.printProgress) { // Print summary only if (options.mode != TREE) { if (!dfalist.empty()) cout << "Main formula:"; dfaPrintVitals(dfa2); Deque<DFA *>::iterator i; Deque<char *>::iterator j; for (i = dfalist2->begin(), j = verifytitlelist->begin(); i != dfalist2->end(); i++, j++) { cout << "\nFormula " << *j << ":"; dfaPrintVitals(*i); } } else { if (!gtalist.empty()) cout << "Main formula:"; gtaPrintTotalSize(gta2); Deque<GTA *>::iterator i; Deque<char *>::iterator j; for (i = gtalist2->begin(), j = verifytitlelist->begin(); i != gtalist2->end(); i++, j++) { cout << "\nFormula " << *j << ":"; gtaPrintTotalSize(*i); } } } if (dfa2 != dfa) { dfaFree(dfa2); for (Deque<DFA *>::iterator i = dfalist2->begin(); i != dfalist2->end(); i++) dfaFree(*i); delete dfalist2; } if (gta2 != gta) { gtaFree(gta2); for (Deque<GTA *>::iterator i = gtalist2->begin(); i != gtalist2->end(); i++) gtaFree(*i); delete gtalist2; } ///////// AUTOMATON ANALYSIS ///////////////////////////////////////////// if (options.analysis) { if (options.printProgress) cout << "\nANALYSIS\n"; if (options.mode != TREE) { if (!dfalist.empty()) cout << "Main formula:\n"; dfaAnalyze(dfa, numVars, vnames, offs, types, options.treemodeOutput); Deque<DFA *>::iterator i; Deque<char *>::iterator j; for (i = dfalist.begin(), j = verifytitlelist->begin(); i != dfalist.end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; dfaAnalyze(*i, numVars, vnames, offs, types, options.treemodeOutput); } } else { if (numTypes == 0 || options.treemodeOutput) { if (!gtalist.empty()) cout << "Main formula:\n"; gtaAnalyze(gta, numVars, vnames, offs, options.graphvizSatisfyingEx, options.graphvizCounterEx); Deque<GTA *>::iterator i; Deque<char *>::iterator j; for (i = gtalist.begin(), j = verifytitlelist->begin(); i != gtalist.end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; gtaAnalyze(*i, numVars, vnames, offs, options.graphvizSatisfyingEx, options.graphvizCounterEx); } } else { if (options.graphvizSatisfyingEx || options.graphvizCounterEx) cout << "Graphviz output of typed trees not implemented.\n"; if (!gtalist.empty()) cout << "Main formula:\n"; gtaTypeAnalyze(gta, numVars, vnames, types, offs, univs, trees); Deque<GTA *>::iterator i; Deque<char *>::iterator j; for (i = gtalist.begin(), j = verifytitlelist->begin(); i != gtalist.end(); i++, j++) { cout << "\nFormula " << *j << ":\n"; gtaTypeAnalyze(*i, numVars, vnames, types, offs, univs, trees); } } } } ///////// CLEAN UP /////////////////////////////////////////////////////// if (options.mode != TREE) { dfaFree(dfa); for (Deque<DFA *>::iterator i = dfalist.begin(); i != dfalist.end(); i++) dfaFree(*i); } else { gtaFree(gta); for (Deque<GTA *>::iterator i = gtalist.begin(); i != gtalist.end(); i++) gtaFree(*i); freeGuide(); } delete verifytitlelist; Deque<FileSource *>::iterator i; for (i = source.begin(); i != source.end(); i++) delete *i; for (ix = 0; ix < numVars; ix++) { delete[] univs[ix]; mem_free(statespaces[ix]); } delete[] statespaces; delete[] vnames; delete[] offs; delete[] types; delete[] univs; delete[] trees; freeTreetypes(); if (options.statistics) print_statistics(); if (options.time) { timer_total.stop(); cout << "\nTotal time: "; timer_total.print(); print_timing(); } else if (options.printProgress) { timer_total.stop(); cout << "\nTotal time: "; timer_total.print(); } #ifdef MAXALLOCATED cout << "Maximum space allocated: " << (maxallocated+524288)/1048576 << " MB\n"; #endif }