Multiway join rules

Add rules to compile query to a plan using HyperCube shuffle and multiway join. 
* [x]  add rule to merge left deep join into nary join in logical plan
* [x]  add rule break nary join to hypercube shuffle and local multiway join
* [x]  add rule to instantiate local multiway join (currently we only have leapfrog, but there could be more, so this part is seperated from break break nary join)
* [x]  add rule to place sort before LeapFrogJoin.
* [x]  add unit test
* [x]  add query test
 

Comment is a little confusing, perhaps because of writing style(*) as well as because the function's not commented.

(*) In writing, both papers and comments, we must always make sure the reader knows what `it` is. In this case, the comment's `it` means `op`, but the next line checks `op.left`. This seeming contradiction might lead a reader (me) down a wrong path.
(**) The same rule about `it` applies to `this`. However, we tend to be more cavalier when the `this` is implied. That is to say, I am guilty of having an unspecific `this` all the time. For an example, see the next paragraph.

I might make this (*this what? this code.*) clearer as follows:

```python
"""Precondition: op is an instance of `ProjectingJoin`. This function collects
all the ProjectingJoin operators in the left subtree and merges them into a single
NaryJoin."""

# if op.left is not a join, nothing to merge. op stays a binary join
```