Skip to content

Commit 5429a24

Browse files
committed
Using Option type instead to mark timeout
1 parent 031a153 commit 5429a24

1 file changed

Lines changed: 28 additions & 32 deletions

File tree

src/main/scala/viper/carbon/verifier/BoogieInterface.scala

Lines changed: 28 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ trait BoogieInterface {
6464
"/proverOpt:O:smt.qi.max_multi_patterns=1000",
6565
s"/proverOpt:PROVER_PATH=$z3Path")
6666

67-
val timeoutErrorName = "TIMEOUT"
68-
6967
/** The (resolved) path where Boogie is supposed to be located. */
7068
def boogiePath: String
7169

@@ -79,7 +77,7 @@ trait BoogieInterface {
7977
// Hence, for now we have to trust Boogie to manage its own sub-processes.
8078
// private var _z3ProcessStream: Option[LazyList[ProcessHandle]] = None
8179

82-
var errormap: Map[Int, AbstractError] = Map()
80+
var errormap: Map[Int, VerificationError] = Map()
8381
var models : collection.mutable.ListBuffer[String] = new collection.mutable.ListBuffer[String]
8482
def invokeBoogie(program: Program, options: Seq[String], timeout: Option[Int]): (String,VerificationResult) = {
8583
// find all errors and assign everyone a unique id
@@ -90,33 +88,35 @@ trait BoogieInterface {
9088
}
9189

9290
// invoke Boogie
93-
val output = run(program.toString, defaultOptions ++ options, timeout)
94-
// parse the output
95-
parse(output, timeout) match {
96-
case (version,Nil) =>
97-
(version,Success)
98-
case (version,errorIds) => {
99-
val errors = (0 until errorIds.length).map(i => {
100-
val id = errorIds(i)
101-
val error = errormap.get(id).get
102-
if (models.nonEmpty) {
103-
error match {
104-
case e: AbstractVerificationError =>
105-
e.failureContexts = Seq(FailureContextImpl(Some(SimpleCounterexample(Model(models(i))))))
106-
case _ =>
107-
}
91+
val optOutput = run(program.toString, defaultOptions ++ options, timeout)
92+
optOutput match {
93+
case None =>
94+
// Timeout
95+
(null, Failure(Seq(TimeoutOccurred(timeout.get, "second(s)"))))
96+
case Some(output) =>
97+
// parse the output
98+
parse(output) match {
99+
case (version, Nil) =>
100+
(version, Success)
101+
case (version, errorIds) => {
102+
val errors = (0 until errorIds.length).map(i => {
103+
val id = errorIds(i)
104+
val error = errormap.get(id).get
105+
if (models.nonEmpty) {
106+
error.failureContexts = Seq(FailureContextImpl(Some(SimpleCounterexample(Model(models(i))))))
107+
}
108+
error
109+
})
110+
(version, Failure(errors))
108111
}
109-
error
110-
})
111-
(version,Failure(errors))
112-
}
112+
}
113113
}
114114
}
115115

116116
/**
117117
* Parse the output of Boogie. Returns a pair of the detected version number and a sequence of error identifiers.
118118
*/
119-
private def parse(output: String, timeout: Option[Int]): (String,Seq[Int]) = {
119+
private def parse(output: String): (String,Seq[Int]) = {
120120
val LogoPattern = "Boogie program verifier version ([0-9.]+),.*".r
121121
val SummaryPattern = "Boogie program verifier finished with ([0-9]+) verified, ([0-9]+) error.*".r
122122
val ErrorPattern = " .+ \\[([0-9]+)\\]".r
@@ -131,13 +131,6 @@ trait BoogieInterface {
131131
errormap += (otherErrId -> internalError)
132132
}
133133

134-
def reportTimeout() = {
135-
otherErrId -= 1
136-
errors += otherErrId
137-
val timeoutError = TimeoutOccurred(timeout.get, "second(s)")
138-
errormap += (otherErrId -> timeoutError)
139-
}
140-
141134
var parsingModel : Option[StringBuilder] = None
142135
var stateInitialBlock = false
143136
for (l <- output.linesIterator) {
@@ -161,7 +154,6 @@ trait BoogieInterface {
161154
case SummaryPattern(v, e) =>
162155
if(e.toInt != errors.size) unexpected(s"Found ${errors.size} errors, but there should be $e. The output was: $output")
163156
case "" => // ignore empty lines
164-
case `timeoutErrorName` if timeout.isDefined => reportTimeout()
165157
case _ =>
166158
unexpected(s"Found an unparsable output from Boogie: $l")
167159
}
@@ -171,6 +163,7 @@ trait BoogieInterface {
171163

172164
/**
173165
* Invoke Boogie.
166+
* Returns None if there was a timeout, otherwise the Boogie output.
174167
*/
175168
private def run(input: String, options: Seq[String], timeout: Option[Int]) = {
176169
reporter report BackendSubProcessReport("carbon", boogiePath, BeforeInputSent, _boogieProcessPid)
@@ -233,7 +226,10 @@ trait BoogieInterface {
233226
val normalOutput = inputConsumer.result.get
234227
reporter report BackendSubProcessReport("carbon", boogiePath, OnExit, _boogieProcessPid)
235228

236-
errorOutput + normalOutput + (if (boogieTimeout) timeoutErrorName else "")
229+
if (boogieTimeout)
230+
None
231+
else
232+
Some(errorOutput + normalOutput)
237233
} catch {
238234
case _: NoSuchElementException => sys.error("Could not retrieve output from Boogie")
239235
}

0 commit comments

Comments
 (0)