Skip to content

Dependency Analysis#976

Open
AndreaKe wants to merge 469 commits into
masterfrom
keuscha/dependency_analysis_refactoring
Open

Dependency Analysis#976
AndreaKe wants to merge 469 commits into
masterfrom
keuscha/dependency_analysis_refactoring

Conversation

@AndreaKe
Copy link
Copy Markdown
Collaborator

Adds the dependency analysis for Silicon. It is disabled by default. When enabled, it analyzes all (direct and indirect) semantic dependencies in the program. The dependencies of a proof obligation indicate which specifications, statements, and assumptions were used to prove that obligation. The analysis builds a dependency graph, which can be exported or queried using the included CLI tool.

@AndreaKe AndreaKe requested a review from marcoeilers May 26, 2026 15:30
@AndreaKe AndreaKe self-assigned this May 26, 2026
Copy link
Copy Markdown
Contributor

@marcoeilers marcoeilers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I had a rough look and left some nitpicky comments and some very general questions; let's discuss those at some point.

def statistics(): Map[String, String]

var dependencyAnalyzer: DependencyAnalyzer
def initDependencyAnalyzer(member: Member, preambleNodes: Iterable[DependencyAnalysisNode]): Unit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit surprised that this is in the Decider.

def assume(assumptions: Iterable[(Term, Option[DebugExp])]): Unit
def assume(assumptions: InsertionOrderedSet[(Term, Option[DebugExp])], enforceAssumption: Boolean = false, isDefinition: Boolean = false): Unit
def assume(terms: Iterable[Term], debugExp: Option[DebugExp], enforceAssumption: Boolean): Unit
def registerChunk[CH <: GeneralChunk](buildChunk: Term => CH, perm: Term, analysisInfo: AnalysisInfo, isExhale: Boolean): CH
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in the Decider? It doesn't feel very Decider-like.

def isPathInfeasible: Boolean

def assume(t: Term, e: Option[ast.Exp], finalExp: Option[ast.Exp], analysisInfos: DependencyAnalysisInfos): Unit
def assume(t: Term, debugExp: Option[DebugExp], analysisInfos: DependencyAnalysisInfos): Unit
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we at some point should summarize the additional information for specific modes (debugging, dependency analysis, Joao has a branch where he is tracking query types #975) in some sort of info argument

}

def registerDerivedChunk[CH <: GeneralChunk](sourceChunks: Set[Chunk], buildChunk: Term => CH, perm: Term, analysisInfo: AnalysisInfo, isExhale: Boolean, createLabel: Boolean=true): CH = {
if(!isDependencyAnalysisEnabled)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wait so this does something even if the analysis is disabled?


val labelNodeOpt = getOrCreateAnalysisLabelNode()

if(isExhale)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Silicon uses if ( (with a space) throughout


val elseBranchVerificationTask: Verifier => VerificationResult =
if (executeElseBranch) {
if (executeElseBranch || Verifier.config.disableInfeasibilityChecks()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a variable skipPathFeasibilityCheck, maybe you could reuse that?

(Q: (State, Heap, Verifier) => VerificationResult)
: VerificationResult = {

val analysisInfos = DependencyAnalysisInfos.DefaultDependencyAnalysisInfos.withSource(StringAnalysisSourceInfo("produce", ast.NoPosition)).withDependencyType(DependencyType.Internal)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That feels like it could be abbreviated :D

: VerificationResult

def eval(s: State, e: ast.Exp, pve: PartialVerificationError, v: Verifier)
def eval(s: State, e: ast.Exp, pve: PartialVerificationError, v: Verifier, analysisInfos: DependencyAnalysisInfos)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sure this is consistent: Verifier used to be last everywhere, now AnalysisInfos are always after the Verifier (I'm not saying it's not consistent, I just didn't pay attention until now)

}

def eval3(s: State, e: ast.Exp, pve: PartialVerificationError, v: Verifier)
def eval3(s: State, e: ast.Exp, pve: PartialVerificationError, v: Verifier, analysisInfos: DependencyAnalysisInfos)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the analysisInfos couldn't possible be part of the State, could they?

override def permMinus(perm: Term, permExp: Option[ast.Exp]): QuantifiedBasicChunk
override def permPlus(perm: Term, permExp: Option[ast.Exp]): QuantifiedBasicChunk
override def withSnapshotMap(snap: Term): QuantifiedBasicChunk
override protected def applyCondition(newCond: Term, newCondExp: Option[ast.Exp]): QuantifiedBasicChunk
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aw, this was such a nice interface though :(

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants