Use range collections to represent seals.

Again, seems like a win; probably should always have been the case but was
overlooked.
Minor code cleanup.
Add another analysis pass to infer seals for flat_map rules.

The observation is that in a rule like

    foo <= bar.flat_map {|b| b.vals.map {|x| [b.key, x]}}

Where y is the first column of foo and "key" is the only key column of bar, we
can generate seal_foo_y(X) facts automatically when we see bar(X, _).