Merge ProjectOps without lEft/rIght

(when possible). This defines a general `merge` on Reshapes that will
combine them into a single Reshape _if_ the fields are either disjoint,
or if the fields in the intersection have identical expressions in both
original Reshapes. If Reshape.merge fails, we fall back to lEft/rIght.

Currently this only affects a few cases, but #391 (unique temp names)
should make it more broadly applicable.

Fixes #388.