Skip to content

Commit a7914f3

Browse files
authored
Merge pull request #631 from mlimbeck/master
Fabio counterexample improvements
2 parents 50eecab + 6045c2a commit a7914f3

17 files changed

Lines changed: 1043 additions & 162 deletions

File tree

src/main/scala/interfaces/Verification.scala

Lines changed: 74 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@
77
package viper.silicon.interfaces
88

99
import viper.silicon.interfaces.state.Chunk
10-
import viper.silicon.reporting.Converter
10+
import viper.silicon.reporting.{Converter, ExtractedModel, ExtractedModelEntry, GenericDomainInterpreter,
11+
ModelInterpreter, ExtractedFunction, DomainEntry, VarEntry, RefEntry, NullRefEntry, UnprocessedModelEntry}
1112
import viper.silicon.state.{State, Store}
12-
import viper.silver.verifier.{Counterexample, FailureContext, Model, VerificationError}
13+
import viper.silver.verifier.{Counterexample, FailureContext, Model, VerificationError, ValueEntry, ApplicationEntry, ConstantEntry}
1314
import viper.silicon.state.terms.Term
15+
import viper.silicon.verifier.Verifier
1416
import viper.silver.ast
1517

1618
/*
@@ -146,19 +148,84 @@ case class SiliconMappedCounterexample(internalStore: Store,
146148
extends SiliconCounterexample {
147149

148150
val converter: Converter =
149-
Converter(nativeModel, internalStore, heap, oldHeaps)
151+
Converter(nativeModel, internalStore, heap, oldHeaps, Verifier.program)
150152

151153
val model: Model = nativeModel
154+
val interpreter: ModelInterpreter[ExtractedModelEntry, Seq[ExtractedModelEntry]] = GenericDomainInterpreter(converter)
155+
private var heapNames: Map[ValueEntry, String] = Map()
152156

153157
override lazy val toString: String = {
154-
val buf = converter.modelAtLabel
155-
.map(x => s"model at label: ${x._1}\n${x._2.toString}\n")
158+
val extractedModel = converter.extractedModel
159+
val bufModels = converter.modelAtLabel
160+
.map { case (label, model) => s"model at label $label:\n${interpret(model).toString}"}
156161
.mkString("\n")
162+
val (bufDomains, bufNonDomainFunctions) = functionsToString()
163+
s"$bufModels\non return: \n${interpret(extractedModel).toString} $bufDomains $bufNonDomainFunctions"
164+
}
165+
private def interpret(t: ExtractedModel): ExtractedModel =
166+
ExtractedModel(t.entries.map{ case (name, entry) => (name, interpret(entry)) })
167+
private def interpret(t: ExtractedModelEntry): ExtractedModelEntry = interpreter.interpret(t, Seq())
168+
169+
private def functionsToString() : (String, String) = {
170+
//extractedModel.entries should be a bijection so we can invert the map
171+
//Since we only care about ref entries we can remove everything else
172+
val invEntries = converter.extractedModel.entries.flatMap{ case (name, entry) =>
173+
entry match {
174+
case RefEntry(symName, _) => Some(symName -> name)
175+
case NullRefEntry(symName)=> Some(symName -> name)
176+
case _ => None
177+
}}
178+
179+
val replaceDomainFunction = converter.domains.map{
180+
case DomainEntry(names, types, functions) =>
181+
DomainEntry(names, types, renameFunctions(functions, invEntries))
182+
}
183+
val bufDomains = replaceDomainFunction.nonEmpty match {
184+
case true => "\nDomain: \n" + replaceDomainFunction.map(domain => domain.toString()).mkString("\n")
185+
case false => ""
186+
}
187+
188+
val replaceNonDomainFunctions = renameFunctions(converter.nonDomainFunctions, invEntries)
189+
val bufNonDomainFunctions = replaceNonDomainFunctions.nonEmpty match {
190+
case true => "\nFunctions: \n" + replaceNonDomainFunctions.map(fn => fn.toString()).mkString("\n")
191+
case false => ""
192+
}
193+
(bufDomains, bufNonDomainFunctions)
194+
}
195+
196+
private def renameFunctions(fn: Seq[ExtractedFunction], invEntries: Map[String, String]) : Seq[ExtractedFunction] = {
197+
fn.map{
198+
case ExtractedFunction(fname, argtypes, returnType, options, default) => {
199+
val optionsNew = options.map(x => x._1.map(y => renameFunction(y, invEntries)) -> renameFunction(x._2, invEntries))
200+
val defaultNew = renameFunction(default, invEntries)
201+
ExtractedFunction(fname, argtypes, returnType, optionsNew, defaultNew)
202+
}
203+
}
204+
}
205+
206+
private def renameFunction(entry:ExtractedModelEntry, invEntries: Map[String, String]): ExtractedModelEntry = {
207+
entry match {
208+
case VarEntry(name, sort) => VarEntry(invEntries.get(name).getOrElse(name), sort)
209+
case UnprocessedModelEntry(unproEntry) => {
210+
unproEntry match {
211+
case ApplicationEntry("$Snap.combine", Seq(_, _)) => renameSnap(unproEntry)
212+
case ConstantEntry("$Snap.unit") => renameSnap(unproEntry)
213+
case _ => entry
214+
}
215+
}
216+
case _ => entry
217+
}
218+
}
157219

158-
s"$buf\non return: \n${converter.extractedModel.toString}"
220+
private def renameSnap(entry: ValueEntry): ExtractedModelEntry = {
221+
if (!heapNames.contains(entry)) {
222+
heapNames += (entry -> ("heap_" + heapNames.size.toString))
223+
}
224+
UnprocessedModelEntry(ConstantEntry(
225+
heapNames.get(entry).orNull))
159226
}
160227

161228
override def withStore(s: Store): SiliconCounterexample = {
162229
SiliconMappedCounterexample(s, heap, oldHeaps, nativeModel)
163230
}
164-
}
231+
}

0 commit comments

Comments
 (0)