1 /********************* */
2 /*! \file command_executor.cpp
4 ** Original author: Morgan Deters
5 ** Major contributors: Andrew Reynolds, Kshitij Bansal
6 ** Minor contributors (to current version): none
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2014 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** information.\endverbatim
12 ** \brief An additional layer between commands and invoking them.
18 #include "main/command_executor.h"
19 #include "expr/command.h"
21 #include "main/main.h"
23 #include "main/options.h"
24 #include "smt/options.h"
27 # include <sys/resource.h>
28 #endif /* ! __WIN32__ */
33 // Function to cancel any (externally-imposed) limit on CPU time.
34 // This is used for competitions while a solution (proof or model)
35 // is being dumped (so that we don't give "sat" or "unsat" then get
36 // interrupted partway through outputting a proof!).
37 void setNoLimitCPU() {
38 // Windows doesn't have these things, just ignore
41 int st
= getrlimit(RLIMIT_CPU
, &rlc
);
43 rlc
.rlim_cur
= rlc
.rlim_max
;
44 setrlimit(RLIMIT_CPU
, &rlc
);
46 #endif /* ! __WIN32__ */
50 void printStatsIncremental(std::ostream
& out
, const std::string
& prvsStatsString
, const std::string
& curStatsString
);
52 CommandExecutor::CommandExecutor(ExprManager
&exprMgr
, Options
&options
) :
54 d_smtEngine(new SmtEngine(&exprMgr
)),
60 bool CommandExecutor::doCommand(Command
* cmd
)
62 if( d_options
[options::parseOnly
] ) {
66 CommandSequence
*seq
= dynamic_cast<CommandSequence
*>(cmd
);
71 for(CommandSequence::iterator subcmd
= seq
->begin();
72 (status
|| d_options
[options::continuedExecution
]) && subcmd
!= seq
->end();
74 status
= doCommand(*subcmd
);
79 if(d_options
[options::verbosity
] > 2) {
80 *d_options
[options::out
] << "Invoking: " << *cmd
<< std::endl
;
83 return doCommandSingleton(cmd
);
87 void CommandExecutor::reset()
89 if(d_options
[options::statistics
]) {
90 flushStatistics(*d_options
[options::err
]);
93 d_smtEngine
= new SmtEngine(&d_exprMgr
);
96 bool CommandExecutor::doCommandSingleton(Command
* cmd
)
99 if(d_options
[options::verbosity
] >= -1) {
100 status
= smtEngineInvoke(d_smtEngine
, cmd
, d_options
[options::out
]);
102 status
= smtEngineInvoke(d_smtEngine
, cmd
, NULL
);
106 CheckSatCommand
* cs
= dynamic_cast<CheckSatCommand
*>(cmd
);
108 d_result
= res
= cs
->getResult();
110 QueryCommand
* q
= dynamic_cast<QueryCommand
*>(cmd
);
112 d_result
= res
= q
->getResult();
115 if((cs
!= NULL
|| q
!= NULL
) && d_options
[options::statsEveryQuery
]) {
116 std::ostringstream ossCurStats
;
117 flushStatistics(ossCurStats
);
118 printStatsIncremental(*d_options
[options::err
], d_lastStatistics
, ossCurStats
.str());
119 d_lastStatistics
= ossCurStats
.str();
122 // dump the model/proof if option is set
125 if( d_options
[options::produceModels
] &&
126 d_options
[options::dumpModels
] &&
127 ( res
.asSatisfiabilityResult() == Result::SAT
||
128 (res
.isUnknown() && res
.whyUnknown() == Result::INCOMPLETE
) ) ) {
129 g
= new GetModelCommand();
130 } else if( d_options
[options::proof
] &&
131 d_options
[options::dumpProofs
] &&
132 res
.asSatisfiabilityResult() == Result::UNSAT
) {
133 g
= new GetProofCommand();
134 } else if( d_options
[options::dumpInstantiations
] &&
135 res
.asSatisfiabilityResult() == Result::UNSAT
) {
136 g
= new GetInstantiationsCommand();
139 //set no time limit during dumping if applicable
140 if( d_options
[options::forceNoLimitCpuWhileDump
] ){
143 status
= doCommandSingleton(g
);
149 bool smtEngineInvoke(SmtEngine
* smt
, Command
* cmd
, std::ostream
*out
)
154 cmd
->invoke(smt
, *out
);
156 // ignore the error if the command-verbosity is 0 for this command
157 if(smt
->getOption(std::string("command-verbosity:") + cmd
->getCommandName()).getIntegerValue() == 0) {
163 void printStatsIncremental(std::ostream
& out
, const std::string
& prvsStatsString
, const std::string
& curStatsString
) {
164 if(prvsStatsString
== "") {
165 out
<< curStatsString
;
170 // if a number, subtract and add that to parantheses
171 std::istringstream
issPrvs(prvsStatsString
);
172 std::istringstream
issCur(curStatsString
);
174 std::string prvsStatName
, prvsStatValue
, curStatName
, curStatValue
;
176 std::getline(issPrvs
, prvsStatName
, ',');
177 std::getline(issCur
, curStatName
, ',');
180 * Stat are assumed to one-per line: "<statName>, <statValue>"
181 * e.g. "sat::decisions, 100"
182 * Output is of the form: "<statName>, <statValue> (<statDiffFromPrvs>)"
183 * e.g. "sat::decisions, 100 (20)"
184 * If the value is not numeric, no change is made.
186 while( !issCur
.eof() ) {
188 std::getline(issCur
, curStatValue
, '\n');
190 if(curStatName
== prvsStatName
) {
191 std::getline(issPrvs
, prvsStatValue
, '\n');
193 double prvsFloat
, curFloat
;
195 (std::istringstream(prvsStatValue
) >> prvsFloat
) &&
196 (std::istringstream(curStatValue
) >> curFloat
);
199 out
<< curStatName
<< ", " << curStatValue
<< " "
200 << "(" << std::setprecision(8) << (curFloat
-prvsFloat
) << ")"
203 out
<< curStatName
<< ", " << curStatValue
<< std::endl
;
206 std::getline(issPrvs
, prvsStatName
, ',');
208 out
<< curStatName
<< ", " << curStatValue
<< std::endl
;
211 std::getline(issCur
, curStatName
, ',');
215 }/* CVC4::main namespace */
216 }/* CVC4 namespace */