Initial add of the generic optimizer code

Before digging into this code, look at the Rules implemented at the bottom of DagOptimizer.

There are several TODOS here:

- [x] After I split the code into separate files, I started hitting a scala 2.9 compiler bug, that I don't hit in 2.10. I'll try to work around, or possibly hope that Twitter finally gets on 2.9 before we need this.

- [x] Tests tests tests. I played around at the repl, but clearly we need super hardcore tests for any optimization framework.

- [ ] Actually call this code from an existing platform.
The dag rewriting is much easier when you have ids associated with each expression. I think it would be cool to only have one, but the conversion between the underlying dags and this representation is much easier when you don't need to worry about the ids.

Expr is basically an implementation detail, so I don't worry too much about having them. But if there is a clean way to remove Expr, I'm all for it.  Note, Expr is really not used when you are writing rules or optimizing.