Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
8c16f3d
Display Failing Branches
7i6ht Jan 18, 2025
1d7424d
Store trees & move class
7i6ht Jan 30, 2025
4f7a805
Clean up
7i6ht Jan 31, 2025
ce1c035
Refactoring + fixes
7i6ht Feb 2, 2025
a441829
Refactoring
7i6ht Feb 4, 2025
472434b
Refactoring
7i6ht Feb 5, 2025
7b25a2e
Add tests
7i6ht Feb 5, 2025
eb50f57
Fix tests
7i6ht Feb 5, 2025
ff10687
Branch Tree: Print single path
7i6ht Feb 17, 2025
213df1d
Fix tests
7i6ht Feb 17, 2025
d8856bc
Really fix tests
7i6ht Feb 17, 2025
1251bb1
Fix tests
7i6ht Feb 19, 2025
d093d43
Revert changes to brancher
7i6ht Feb 26, 2025
b82921f
Revert unwanted changes to consumer
7i6ht Feb 26, 2025
e1c0494
Revert unwanted changes to state
7i6ht Feb 26, 2025
2c05828
Revert unwanted changes to state
7i6ht Feb 26, 2025
23682f9
Revert unwanted changes to state
7i6ht Feb 26, 2025
7a468de
Revert unwanted changes to DefaultMainVerifier
7i6ht Feb 26, 2025
28a6cc0
Revert unwanted changes to State
7i6ht Feb 26, 2025
7d3b6f1
Collect all failures
7i6ht Feb 28, 2025
f41d858
Change size check
7i6ht Mar 2, 2025
326c5e5
Remove braces
7i6ht Mar 2, 2025
bfe81d3
Fix
7i6ht Mar 2, 2025
c461458
Renaming
7i6ht Mar 2, 2025
63898f1
Clean up
7i6ht Mar 3, 2025
01f7bf1
Dot representation + report whole tree
7i6ht Mar 4, 2025
93189b9
Concurrent Map inside branchTreeMap
7i6ht Mar 4, 2025
4eb19d9
Make dot file path absolute
7i6ht Mar 4, 2025
089fc05
Add missing change
7i6ht Mar 7, 2025
29d114d
Add missing change
7i6ht Mar 7, 2025
370c675
Change back from reporting to errors
7i6ht Mar 7, 2025
bf1a48d
Refactoring
7i6ht Mar 9, 2025
692e9e2
Refactoring
7i6ht Mar 9, 2025
9a70060
Refactoring
7i6ht Mar 9, 2025
1a04d4f
Refactoring
7i6ht Mar 9, 2025
11f2d7a
Undo changes
7i6ht Mar 10, 2025
3f11384
Remove TODO
7i6ht Mar 10, 2025
d35072c
Readd missing files
7i6ht Mar 10, 2025
d0f1316
Switch to reporting
7i6ht Mar 10, 2025
661c537
Generate ASCII / DOT client side
7i6ht Mar 14, 2025
24612ab
Remove unused import
7i6ht Mar 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/main/scala/decider/Decider.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import viper.silicon.state.terms.{Term, _}
import viper.silicon.utils.ast.{extractPTypeFromExp, simplifyVariableName}
import viper.silicon.verifier.{Verifier, VerifierComponent}
import viper.silver.ast
import viper.silver.ast.{LocalVarWithVersion, NoPosition}
import viper.silver.ast.{Exp, LocalVarWithVersion, NoPosition}
import viper.silver.components.StatefulComponent
import viper.silver.parser.{PKw, PPrimitiv, PReserved, PType}
import viper.silver.reporter.{ConfigurationConfirmation, InternalWarningMessage}
Expand Down Expand Up @@ -129,7 +129,7 @@ trait DefaultDeciderProvider extends VerifierComponent { this: Verifier =>
private var _proverOptions: Map[String, String] = Map.empty
private var _proverResetOptions: Map[String, String] = Map.empty
private val _debuggerAssumedTerms: mutable.Set[Term] = mutable.Set.empty

def functionDecls: Set[FunctionDecl] = _declaredFreshFunctions
def macroDecls: Vector[MacroDecl] = _declaredFreshMacros

Expand Down Expand Up @@ -256,6 +256,16 @@ trait DefaultDeciderProvider extends VerifierComponent { this: Verifier =>

def setPathConditionMark(): Mark = pathConditions.mark()

def getBranchConditionsExp(): Seq[Exp] = {
this.pcs.branchConditionExps.map(_._1)
.filterNot(e => e.isInstanceOf[viper.silver.ast.TrueLit]) /* remove "true" bcs introduced by viper.silicon.utils.ast.BigAnd */
.sortBy(_.pos match {
/* Order branchconditions according to source position */
case pos: viper.silver.ast.HasLineColumn => (pos.line, pos.column)
case _ => (-1, -1)
})
}

/* Assuming facts */

def startDebugSubExp(): Unit = {
Expand Down
13 changes: 12 additions & 1 deletion src/main/scala/decider/PathConditions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import viper.silicon.state.terms._
import viper.silicon.utils.Counter
import viper.silicon.verifier.Verifier
import viper.silver.ast
import viper.silver.ast.TrueLit
import viper.silver.ast.{Exp, TrueLit}
/*
* Interfaces
*/
Expand Down Expand Up @@ -61,6 +61,7 @@ trait RecordedPathConditions {

trait PathConditionStack extends RecordedPathConditions {
def setCurrentBranchCondition(condition: Term, conditionExp: (ast.Exp, Option[ast.Exp])): Unit
def getBranchConditionsExp(): Seq[Exp]
def add(assumption: Term): Unit
def addDefinition(assumption: Term): Unit
def add(declaration: Decl): Unit
Expand Down Expand Up @@ -459,6 +460,16 @@ private[decider] class LayeredPathConditionStack
layers.head.branchConditionExp = conditionExp
}

def getBranchConditionsExp(): Seq[Exp] = {
branchConditionExps.map(_._1)
.filterNot(e => e.isInstanceOf[viper.silver.ast.TrueLit]) /* remove "true" bcs introduced by viper.silicon.utils.ast.BigAnd */
.sortBy(_.pos match {
/* Order branchconditions according to source position */
case pos: viper.silver.ast.HasLineColumn => (pos.line, pos.column)
case _ => (-1, -1)
})
}

def startDebugSubExp(): Unit = {
layers.head.startDebugSubExp()
}
Expand Down
17 changes: 13 additions & 4 deletions src/main/scala/interfaces/Verification.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import viper.silicon.state.terms.{FunctionDecl, MacroDecl, Term}
import viper.silicon.state.{State, Store}
import viper.silicon.verifier.Verifier
import viper.silver.ast
import viper.silver.ast.Program
import viper.silver.ast.{Exp, Program}
import viper.silver.reporter.ExploredBranches
import viper.silver.verifier._

/*
Expand All @@ -28,9 +29,19 @@ import viper.silver.verifier._
/* TODO: Make VerificationResult immutable */
sealed abstract class VerificationResult {
var previous: Vector[VerificationResult] = Vector() //Sets had problems with equality
var exploredBranchPaths: Vector[(Seq[Exp],Boolean)] = Vector()
val continueVerification: Boolean = true
var isReported: Boolean = false

def getExploredBranchPaths(r: VerificationResult = this) : Vector[(Seq[Exp], Boolean)] = {
r.exploredBranchPaths ++ r.previous.flatMap(x => x.previous.length match {
case 0 => x.exploredBranchPaths
case _ =>
val recRes = x.previous.flatMap(getExploredBranchPaths)
x.exploredBranchPaths ++ recRes
})
}

def isFatal: Boolean
def &&(other: => VerificationResult): VerificationResult

Expand Down Expand Up @@ -61,7 +72,6 @@ sealed abstract class VerificationResult {
}
this
}

}
}

Expand Down Expand Up @@ -98,9 +108,8 @@ case class Unreachable() extends NonFatalResult {
case class Failure/*[ST <: Store[ST],
H <: Heap[H],
S <: State[ST, H, S]]*/
(message: VerificationError, override val continueVerification: Boolean = true)
(message: VerificationError, override val continueVerification: Boolean = true, var exploredBranches : Option[ExploredBranches] = None)
extends FatalResult {

override lazy val toString: String = message.readableMessage
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/reporting/package.scala
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ package object reporting {
def convertToViperResult(result: VerificationResult): VprVerificationResult = {
result match {
case Success() | Unreachable() => VprSuccess
case Failure(message, _) => VprFailure(Seq(message))
case Failure(message, _, exploredBranches) => VprFailure(Seq(message), exploredBranches)
}
}

Expand All @@ -58,7 +58,7 @@ package object reporting {
.collect { case failure: VprFailure => failure.errors }
.flatten match {
case Seq() => VprSuccess
case errors => VprFailure(errors)
case errors => VprFailure(errors, results.collectFirst({case Failure(_,_,Some(exploredBranches)) => exploredBranches}))
}
}
}
5 changes: 3 additions & 2 deletions src/main/scala/rules/Consumer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,6 @@ object consumer extends ConsumptionRules {
)
}


private def evalAndAssert(s: State, e: ast.Exp, returnSnap: Boolean, pve: PartialVerificationError, v: Verifier)
(Q: (State, Option[Term], Verifier) => VerificationResult)
: VerificationResult = {
Expand Down Expand Up @@ -620,7 +619,9 @@ object consumer extends ConsumptionRules {
v2.decider.assert(termToAssert) {
case true =>
v2.decider.assume(t, Option.when(withExp)(e), eNew)
QS(s3, v2)
val r = QS(s3, v2)
r.exploredBranchPaths +:= (v.decider.pcs.getBranchConditionsExp(),false)
r
case false =>
val failure = createFailure(pve dueTo AssertionFalse(e), v2, s3, termToAssert, eNew)
if (s3.retryLevel == 0 && v2.reportFurtherErrors()){
Expand Down
18 changes: 6 additions & 12 deletions src/main/scala/rules/SymbolicExecutionRules.scala
Original file line number Diff line number Diff line change
Expand Up @@ -84,26 +84,20 @@ trait SymbolicExecutionRules {
None
}

val branchconditions = if (Verifier.config.enableBranchconditionReporting()) {
v.decider.pcs.branchConditionExps.map(_._1)
.filterNot(e => e.isInstanceOf[viper.silver.ast.TrueLit]) /* remove "true" bcs introduced by viper.silicon.utils.ast.BigAnd */
.sortBy(_.pos match {
/* Order branchconditions according to source position */
case pos: viper.silver.ast.HasLineColumn => (pos.line, pos.column)
case _ => (-1, -1)
})
} else Seq()
val branchConditions = v.decider.pcs.getBranchConditionsExp()

if (Verifier.config.enableDebugging()){
val assumptions = v.decider.pcs.assumptionExps
res.failureContexts = Seq(SiliconDebuggingFailureContext(v.decider.pcs.branchConditions, v.decider.pcs.branchConditionExps.map(bce => bce._1 -> bce._2.get),
counterexample, reasonUnknown, Some(s), Some(v), v.decider.prover.getAllEmits(), v.decider.prover.preambleAssumptions,
v.decider.macroDecls, v.decider.functionDecls, assumptions, failedAssert, failedAssertExp.get))
} else {
res.failureContexts = Seq(SiliconFailureContext(branchconditions, counterexample, reasonUnknown))
val branchConditionsReported = if (Verifier.config.enableBranchconditionReporting()) branchConditions else Seq()
res.failureContexts = Seq(SiliconFailureContext(branchConditionsReported, counterexample, reasonUnknown))
}

Failure(res, v.reportFurtherErrors())

val f = Failure(res, v.reportFurtherErrors())
f.exploredBranchPaths +:= (branchConditions, true)
f
}
}
22 changes: 21 additions & 1 deletion src/main/scala/supporters/MethodSupporter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import viper.silicon.state.{Heap, State, Store}
import viper.silicon.state.State.OldHeaps
import viper.silicon.verifier.{Verifier, VerifierComponent}
import viper.silicon.utils.freshSnap
import viper.silver.reporter.AnnotationWarning
import viper.silver.reporter.{AnnotationWarning, ExploredBranches, ExploredBranchesReport}
import viper.silicon.{Map, toMap}

/* TODO: Consider changing the DefaultMethodVerificationUnitProvider into a SymbolicExecutionRule */
Expand Down Expand Up @@ -117,6 +117,26 @@ trait DefaultMethodVerificationUnitProvider extends VerifierComponent { v: Verif
v.decider.resetProverOptions()

symbExLog.closeMemberScope()

val exploredBranchPaths = result.getExploredBranchPaths()
result match {
case f: Failure if exploredBranchPaths.nonEmpty =>
val transformedPaths = exploredBranchPaths.map(eb => {
val (exps, isResultFatal) = eb
val transformedExps = exps.map(e => {
val (exprStr, negated) = e match {
case ast.Not(expr) => (expr.toString, true)
case _ => (e.toString, false)
}
(exprStr, negated)
}).toVector
(transformedExps, isResultFatal)
})
val exploredBranches = ExploredBranches(method, transformedPaths)
f.exploredBranches = Some(exploredBranches)
v.reporter.report(ExploredBranchesReport(exploredBranches))
case _ =>
}
Seq(result)
}

Expand Down
2 changes: 1 addition & 1 deletion src/main/scala/verifier/DefaultMainVerifier.scala
Original file line number Diff line number Diff line change
Expand Up @@ -630,4 +630,4 @@ class DefaultMainVerifier(config: Config,
*/
private def extractAllVerificationResults(res: VerificationResult): Seq[VerificationResult] =
res :: res.previous.toList
}
}
4 changes: 2 additions & 2 deletions src/test/scala/SiliconQuantifierWeightTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,13 @@ class SiliconQuantifierWeightTests extends AnyFunSuite {
// A small weight should allow the axiom to be instantiated
verifyUsingWeight(1) match {
case Success => // Ok
case Failure(errors) => assert(false)
case Failure(errors,_) => assert(false)
}

// A big weight should prevent the axiom from being instantiated
verifyUsingWeight(999) match {
case Success => assert(false)
case Failure(errors) => // Ok
case Failure(errors,_) => // Ok
}
}
}
2 changes: 1 addition & 1 deletion src/test/scala/SymbExLoggerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class SiliconFrontendWithUnitTesting(path: Path) extends SiliconFrontend(NoopRep
case Nil => super.result
case s1:Seq[AbstractError] => super.result match{
case SilSuccess => SilFailure(s1)
case SilFailure(s2) => SilFailure(s2 ++ s1)
case SilFailure(s2,exploredBranches) => SilFailure(s2 ++ s1,exploredBranches)
}
}
}
Expand Down
7 changes: 4 additions & 3 deletions src/test/scala/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@

import java.nio.file.{Path, Paths}
import viper.silver.ast.Program
import viper.silver.frontend.{SilFrontend, SilFrontendConfig, DefaultStates}
import viper.silver.frontend.{DefaultStates, SilFrontend, SilFrontendConfig}
import viper.silver.verifier.{AbstractError, AbstractVerificationError, VerificationResult, Verifier, Failure => SilFailure}
import viper.silicon.Silicon
import viper.silver.reporter.Reporter

package object tests {
class DummyFrontend extends SilFrontend {
Expand Down Expand Up @@ -59,11 +60,11 @@ package object tests {

def verifyProgram(program: Program, frontend: SilFrontend): VerificationResult = {
frontend.verifier.verify(program) match {
case SilFailure(errors) =>
case SilFailure(errors,exploredBranches) =>
SilFailure(errors.map {
case a: AbstractVerificationError => a.transformedError()
case rest => rest
})
},exploredBranches)
case rest => rest
}
}
Expand Down