Skip to content

Add debug option to dump blocker graph - #163

Open
gsps wants to merge 1 commit into
scala-2.13from
add-blocker-graph-debug
Open

Add debug option to dump blocker graph#163
gsps wants to merge 1 commit into
scala-2.13from
add-blocker-graph-debug

Conversation

@gsps

@gsps gsps commented Sep 3, 2021

Copy link
Copy Markdown
Contributor

Adds a debug section blocker-graph that dumps the (non-strict) implication graph among all blocking literals. The current graph is dumped at the end of checkAssumptions and saved in blocker-graphs/*file*-*n*.dot.

Nodes that correspond to defBlockers also contain the corresponding function name and the call site's position. The positional information is unreliable, since we only store the call site position when the callee's FunctionTemplate is first cached (the cache key being the TypedFunDef).

As an example, the following program requires multiple unfolding steps to prove the assertion in testUnfoldMe:

object MustUnfoldThriceExample {
  def unfoldMe(xs: List[BigInt]): BigInt = {
    require(xs.forall(_ >= 0))
    xs match {
      case Nil() => BigInt(0)
      case Cons(x, xs0) => x + unfoldMe(xs0)
    }
  } ensuring (_ >= 0)

  def testUnfoldMe(xs: List[BigInt]): Unit = {
    require(xs.size >= 3 && xs.forall(_ >= 0))
    val sum = unfoldMe(xs)
    assert(sum >= xs(0) + xs(1) + xs(2))
  }
}

Running with --debug=blocker-graph yields multiple .dot files, one of which corresponds to the assertion's VC:
must-unfold-thrice.pdf

@samarion Any preference on where to move the dot-graph-dumping code that new lives in checkAssumptions?

@gsps
gsps requested a review from samarion September 3, 2021 14:28

@samarion samarion left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe you could add an UnrollingDebugger trait similarly to the SMTLIBDebugger and have it override checkAssumptions?

Comment on lines +41 to +42
// Note: This position is best-effort, since function templates are cached.
val call: Expr = tfd.applied(fdArgs).setPos(pos)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is the goal here to ensure that all calls in the dumped blocker graph have positions? If so, I don't think you need to set a position on this call because it should never be part of the blocker graph.

(If possible, I'd like to avoid making positions part of the FunctionTemplate API)

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.

2 participants