Node merging to reduce branching for CSE
Opened this issue · 6 comments
Currently we have the minimize_kcfg
routine, which pulls branches up to the top of a the KCFG, and unions edges together. That can improve performance of a transition system by reducing the amount of rules that are injected into the definition, but does not reduce overall branching factor of the function. Here is a link to a diagram for references: https://docs.google.com/drawings/d/1l8i_aUMcL8E7WyxHmk2cqRIY74fQ-yvMdhhdDNcOUp0/edit.
In this diagram, on the left, we've already run the existing KCFG minimization routine which lifts splits to the top and collapses subsequent edges into a single edge. We want to transform it into the diagram on the right, which has pushed the split forward through the edges that come after it. In order to make this transformation preserve information, we make the following adjustments:
Edge
s now store a list of tuples(depth, rules, condition)
, which means that "fromsource
node, givencondition
, you will reachtarget
node usingrules
atdepth
". Current edges in the KCFG just store a singledepth, rules
, withcondition
always being#Top
.- When we see a split with edges following, we run a semantics-specific heuristic called
merge_nodes(CTerm, CTerm) -> bool
on the nodes following the edges. In the case of the diagram, we pairwise run it on all ofB
,C
,D
(or do it iteratively for each pair and do smaller mergings). If two nodes (such asB
andC
) havemerge_nodes
returnTrue
, we do the following:- Compute the node
B \/ C
, which has fresh variables in places where the configurations differ, and the specific assignments to the fresh variables conditioned on the path-condition from teh split node leading to each node. So for example, ifE
represents the more abstract configuration, we would computeE #And { PC1 #Implies SUBST1 } #And { PC2 #Implies SUBST2 }
, whereSUBST1
instantiatesE
toB
, andSUBST2
instantiatesE
toC
. - Remove nodes
A1
andA2
from the graph, and insert new nodeB \/ C
, and insert an edge fromA
toB \/ C
with edge data[(d1, PC1), (d2, PC2)]
, and insert a split fromB \/ C
toB
andC
with conditionsPC1
,PC2
. - Repeat procedure with other splits followed by edges, where the user-supplied heuristic fires on the edge targets.
- Compute the node
This effectively "pushes splits down", allowing us to reduce the overall branching factor of the proof if we can push them all the way down to the target node of the proof.
@palinatolmach can you assign the correct people to this, please?
Will assign to @Stevengre once he's added to the org, thanks @Baltoli!
Hi @palinatolmach! Thank you for reminding me about joining the org. I just realized that I had only enabled 2FA on my account a few days ago, but I didn't actually join the organization. Sorry for the delay, and I'll make sure to join the org now.
I want to optimize cterms_anti_unify
, but I've decided to give up because implementing it for multiple variables is challenging. Keeping it simple helps ensure correctness. If this simple formula would reduce the verification time significantly, I will attempt to optimize it with a correct algorithm.
Thought:
- construct a tree from top vars (V_0) to bottom vars/tokens (X).
- given
V_n ==K X
, replaceV_n
byV_0
- lift the constraints
I'm uncertain whether this algorithm is correct for multiple variables; it needs to be tested on more complex cases.