tdd for bug #245: dead code elimination in presence of loops

The dead code elimination does not catch variables that are computed in
the loop but have no effect on the stores. This is probably expected
with the current design, but now that we have DoWhile support in the
execution engine we should revisit.

See bug #245.
cfg: fix typo in __str__

I cannot find a way in which that field c is ever set.
query test for bug #245

An empty program should return a MyrialCompileException even if it has a
dead DoWhile loop in it.
Add dead loop elimination
Another test of dead loop elimination
Add a comment
cfg: make code more Pythonic

Use `{a: b}` for creating a dict
cfg_test: slightly tweak test case

make sure it deletes the loop even when the first x is referenced
cfg: add a comment to dead_loop_elimination
cfg_test: test consecutive unrelated dead loops

The code in dead_loop_elimination can, in principle, delete two loops
at once. Let's test this and expose a bug ;)
dead_loop_elimination: make it recursive

and test it. Has the same bug as prior commit.
Fix recursive application of dead loop elimination
Merge pull request #246 from uwescience/fix-245

[WIP] fix bug #245
Merge branch 'master' into disable-temp-store
raco-wide: change the interface to compiling/optimizing

We really don't want to pass around (name, op) pairs with implicit
parallel execution semantics. Instead, let's actually instantiate
Store/StoreTemp for the IDBs/Relations we want to define and add a
Parallel, Sequence, DoWhile for the operations we want to run in
parallel, in series, or in a loop. Implement this API change and then
update all the tests and calling code to support it.

TODO: I disabled rather than fixed the Grappa and Clang tests.
datalog: make . and ; equivalent EOL characters

Ran into some bugs with the example queries, actually. (Not sure how
they ever worked.)