Refactor merging into a merge pool

This refactors the graph merging logic out of the dependency solver into a ‘merge pool’, a memoizing cache of merged/simplified nodes.  This allows us to do more graph merging later. It also lets us test the merge algorithm itself.