Skip to content

Commit 1952ed9

Browse files
committed
Refactor @traceInduct clustering implementation
1 parent 4c32479 commit 1952ed9

File tree

4 files changed

+67
-83
lines changed

4 files changed

+67
-83
lines changed

core/src/main/scala/stainless/Report.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,15 +104,15 @@ trait AbstractReport[SelfType <: AbstractReport[SelfType]] { self: SelfType =>
104104
val res = for {
105105
RecordRow(id, pos, level, extra, time) <- annotatedRows
106106
if(level == Level.Error && id == identifier)
107-
}yield (id, level)
107+
} yield (id, level)
108108
!res.isEmpty
109109
}
110110

111111
def isUnknown(identifier: Identifier)(implicit ctx: inox.Context): Boolean = {
112112
val res = for {
113113
RecordRow(id, pos, level, extra, time) <- annotatedRows
114114
if(level == Level.Warning && id == identifier)
115-
}yield (id, level)
115+
} yield (id, level)
116116
!res.isEmpty
117117
}
118118

core/src/main/scala/stainless/extraction/trace/Trace.scala

Lines changed: 37 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ package stainless
44
package extraction
55
package trace
66

7+
import stainless.utils.CheckFilter
8+
79
trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self =>
810
val s: Trees
911
val t: termination.Trees
@@ -28,14 +30,14 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
2830
import symbols._
2931
import trees._
3032

31-
val models = symbols.functions.values.toList.filter(elem => isModel(elem.id)).map(elem => elem.id)
32-
val functions = symbols.functions.values.toList.filter(elem => shouldBeChecked(elem.id)).map(elem => elem.id)
33-
3433
if (Trace.getModels.isEmpty) {
34+
val models = symbols.functions.values.toList.filter(elem => isModel(elem.id)).map(elem => elem.id)
3535
Trace.setModels(models)
3636
Trace.nextModel
3737
}
38+
3839
if (Trace.getFunctions.isEmpty) {
40+
val functions = symbols.functions.values.toList.filter(elem => shouldBeChecked(elem.id)).map(elem => elem.id)
3941
Trace.setFunctions(functions)
4042
Trace.nextFunction
4143
}
@@ -44,10 +46,9 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
4446

4547
def freshId(a: Identifier, b: Identifier): Identifier = {
4648
localCounter = localCounter + 1
47-
new Identifier(fixedFullName(a)+"$"+fixedFullName(b),localCounter,localCounter)
49+
new Identifier(CheckFilter.fixedFullName(a)+"$"+CheckFilter.fixedFullName(b),localCounter,localCounter)
4850
}
4951

50-
//if (fd1 != fd2) && (fd1.params.size == fd2.params.size)
5152
def checkPair(fd1: s.FunDef, fd2: s.FunDef): s.FunDef = {
5253

5354
val newParams = fd1.params.map{param => param.freshen}
@@ -68,6 +69,7 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
6869
case (Some(model), Some(function)) => {
6970
val m = symbols.functions.filter(elem => elem._2.id == model).head._2
7071
val f = symbols.functions.filter(elem => elem._2.id == function).head._2
72+
//if (fd1 != fd2) && (fd1.params.size == fd2.params.size)
7173
val newFun = checkPair(m, f)
7274
Trace.setTrace(newFun.id)
7375
List(newFun)
@@ -204,28 +206,10 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
204206

205207
}
206208

207-
//from CheckFilter.scala
208209
type Path = Seq[String]
209-
private def fullNameToPath(fullName: String): Path = (fullName split '.').toSeq
210-
211-
// TODO this is probably done somewhere else in a cleaner fasion...
212-
private def fixedFullName(id: Identifier): String = id.fullName
213-
.replaceAllLiterally("$bar", "|")
214-
.replaceAllLiterally("$up", "^")
215-
.replaceAllLiterally("$eq", "=")
216-
.replaceAllLiterally("$plus", "+")
217-
.replaceAllLiterally("$minus", "-")
218-
.replaceAllLiterally("$times", "*")
219-
.replaceAllLiterally("$div", "/")
220-
.replaceAllLiterally("$less", "<")
221-
.replaceAllLiterally("$geater", ">")
222-
.replaceAllLiterally("$colon", ":")
223-
.replaceAllLiterally("$amp", "&")
224-
.replaceAllLiterally("$tilde", "~")
225-
226210

227211
private lazy val pathsOpt: Option[Seq[Path]] = context.options.findOption(optCompareFuns) map { functions =>
228-
functions map fullNameToPath
212+
functions map CheckFilter.fullNameToPath
229213
}
230214

231215
private def shouldBeChecked(fid: Identifier): Boolean = pathsOpt match {
@@ -234,15 +218,15 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
234218
case Some(paths) =>
235219
// Support wildcard `_` as specified in the documentation.
236220
// A leading wildcard is always assumes.
237-
val path: Path = fullNameToPath(fixedFullName(fid))
221+
val path: Path = CheckFilter.fullNameToPath(CheckFilter.fixedFullName(fid))
238222
paths exists { p =>
239223
if (p endsWith Seq("_")) path containsSlice p.init
240224
else path endsWith p
241225
}
242226
}
243227

244228
private lazy val pathsOptModels: Option[Seq[Path]] = context.options.findOption(optModels) map { functions =>
245-
functions map fullNameToPath
229+
functions map CheckFilter.fullNameToPath
246230
}
247231

248232
private def isModel(fid: Identifier): Boolean = pathsOptModels match {
@@ -251,7 +235,7 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
251235
case Some(paths) =>
252236
// Support wildcard `_` as specified in the documentation.
253237
// A leading wildcard is always assumes.
254-
val path: Path = fullNameToPath(fixedFullName(fid))
238+
val path: Path = CheckFilter.fullNameToPath(CheckFilter.fixedFullName(fid))
255239
paths exists { p =>
256240
if (p endsWith Seq("_")) path containsSlice p.init
257241
else path endsWith p
@@ -260,19 +244,20 @@ trait Trace extends CachingPhase with SimpleFunctions with IdentitySorts { self
260244

261245
}
262246

263-
264247
object Trace {
265-
var boxes: Map[Identifier, List[Identifier]] = Map()
248+
var clusters: Map[Identifier, List[Identifier]] = Map()
266249
var errors: List[Identifier] = List()
267250
var unknowns: List[Identifier] = List()
268251

269252
def printEverything() = {
270-
System.out.println("boxes")
271-
System.out.println(boxes)
272-
System.out.println("errors")
273-
System.out.println(errors)
274-
System.out.println("unknowns")
275-
System.out.println(unknowns)
253+
if(!clusters.isEmpty || !errors.isEmpty || !unknowns.isEmpty) {
254+
System.out.println("clusters")
255+
System.out.println(clusters)
256+
System.out.println("errors")
257+
System.out.println(errors)
258+
System.out.println("unknowns")
259+
System.out.println(unknowns)
260+
}
276261
}
277262

278263
var allModels: List[Identifier] = List()
@@ -297,7 +282,7 @@ object Trace {
297282
def setModels(m: List[Identifier]) = {
298283
allModels = m
299284
tmpModels = m
300-
boxes = (m zip m.map(_ => Nil)).toMap
285+
clusters = (m zip m.map(_ => Nil)).toMap
301286
}
302287

303288
def setFunctions(f: List[Identifier]) = {
@@ -309,7 +294,6 @@ object Trace {
309294

310295
def getFunctions = allFunctions
311296

312-
313297
//model for the current iteration
314298
def getModel = model
315299

@@ -360,23 +344,33 @@ object Trace {
360344
}
361345
}
362346

363-
def isDone = function == None
347+
def nextIteration[T <: AbstractReport[T]](report: AbstractReport[T])(implicit context: inox.Context): Boolean = trace match {
348+
case Some(t) => {
349+
if (report.isError(t)) reportError
350+
else if (report.isUnknown(t)) reportUnknown
351+
else reportValid
352+
!isDone
353+
}
354+
case None => false
355+
}
356+
357+
private def isDone = function == None
364358

365-
def reportError = {
359+
private def reportError = {
366360
errors = function.get::errors
367361
nextFunction
368362
}
369363

370-
def reportUnknown = {
364+
private def reportUnknown = {
371365
nextModel
372-
if(model == None){
366+
if (model == None) {
373367
unknowns = function.get::unknowns
374368
nextFunction
375369
}
376370
}
377371

378-
def reportValid = {
379-
boxes = boxes + (model.get -> (function.get::boxes(model.get)))
372+
private def reportValid = {
373+
clusters = clusters + (model.get -> (function.get::clusters(model.get)))
380374
nextFunction
381375
}
382376
}

core/src/main/scala/stainless/frontend/BatchedCallBack.scala

Lines changed: 7 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -103,35 +103,22 @@ class BatchedCallBack(components: Seq[Component])(implicit val context: inox.Con
103103
reportError(defn.getPos, e.getMessage, symbols)
104104
}
105105

106-
var reports = runs map { run =>
107-
val ids = symbols.functions.keys.toSeq
108-
val analysis = Await.result(run(ids, symbols, filterSymbols = true), Duration.Inf)
109-
RunReport(run)(analysis.toReport)
110-
}
111-
112-
report = Report(reports)
113-
114-
if (report.isError(Trace.getTrace.get)) Trace.reportError
115-
else if (report.isUnknown(Trace.getTrace.get)) Trace.reportUnknown
116-
else Trace.reportValid
106+
var rerunPipeline = true
117107

118-
while (!Trace.isDone) {
119-
report.emit(context)
120-
121-
reports = runs map { run =>
108+
while (rerunPipeline) {
109+
val reports = runs map { run =>
122110
val ids = symbols.functions.keys.toSeq
123111
val analysis = Await.result(run(ids, symbols, filterSymbols = true), Duration.Inf)
124112
RunReport(run)(analysis.toReport)
125113
}
126114

127115
report = Report(reports)
116+
rerunPipeline = Trace.nextIteration(report)
128117

129-
if (report.isError(Trace.getTrace.get)) Trace.reportError
130-
else if (report.isUnknown(Trace.getTrace.get)) Trace.reportUnknown
131-
else Trace.reportValid
118+
if (rerunPipeline) report.emit(context)
119+
else Trace.printEverything
132120
}
133-
134-
extraction.trace.Trace.printEverything
121+
135122
}
136123

137124
def stop(): Unit = {

core/src/main/scala/stainless/utils/CheckFilter.scala

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,9 @@ trait CheckFilter {
1010
import trees._
1111

1212
type Path = Seq[String]
13-
private def fullNameToPath(fullName: String): Path = (fullName split '.').toSeq
14-
15-
// TODO this is probably done somewhere else in a cleaner fasion...
16-
private def fixedFullName(id: Identifier): String = id.fullName
17-
.replaceAllLiterally("$bar", "|")
18-
.replaceAllLiterally("$up", "^")
19-
.replaceAllLiterally("$eq", "=")
20-
.replaceAllLiterally("$plus", "+")
21-
.replaceAllLiterally("$minus", "-")
22-
.replaceAllLiterally("$times", "*")
23-
.replaceAllLiterally("$div", "/")
24-
.replaceAllLiterally("$less", "<")
25-
.replaceAllLiterally("$geater", ">")
26-
.replaceAllLiterally("$colon", ":")
27-
.replaceAllLiterally("$amp", "&")
28-
.replaceAllLiterally("$tilde", "~")
2913

3014
private lazy val pathsOpt: Option[Seq[Path]] = context.options.findOption(optFunctions) map { functions =>
31-
functions map fullNameToPath
15+
functions map CheckFilter.fullNameToPath
3216
}
3317

3418
private def shouldBeChecked(fid: Identifier, flags: Seq[trees.Flag]): Boolean = pathsOpt match {
@@ -40,7 +24,7 @@ trait CheckFilter {
4024
case Some(paths) =>
4125
// Support wildcard `_` as specified in the documentation.
4226
// A leading wildcard is always assumes.
43-
val path: Path = fullNameToPath(fixedFullName(fid))
27+
val path: Path = CheckFilter.fullNameToPath(CheckFilter.fixedFullName(fid))
4428
paths exists { p =>
4529
if (p endsWith Seq("_")) path containsSlice p.init
4630
else path endsWith p
@@ -86,5 +70,24 @@ object CheckFilter {
8670
override val context = ctx
8771
override val trees: t.type = t
8872
}
73+
74+
type Path = Seq[String]
75+
76+
def fullNameToPath(fullName: String): Path = (fullName split '.').toSeq
77+
78+
// TODO this is probably done somewhere else in a cleaner fasion...
79+
def fixedFullName(id: Identifier): String = id.fullName
80+
.replaceAllLiterally("$bar", "|")
81+
.replaceAllLiterally("$up", "^")
82+
.replaceAllLiterally("$eq", "=")
83+
.replaceAllLiterally("$plus", "+")
84+
.replaceAllLiterally("$minus", "-")
85+
.replaceAllLiterally("$times", "*")
86+
.replaceAllLiterally("$div", "/")
87+
.replaceAllLiterally("$less", "<")
88+
.replaceAllLiterally("$geater", ">")
89+
.replaceAllLiterally("$colon", ":")
90+
.replaceAllLiterally("$amp", "&")
91+
.replaceAllLiterally("$tilde", "~")
8992
}
9093

0 commit comments

Comments
 (0)