Add safety check for cross-theory recursion

This sequence of changes allows people to create multiple policies
and then write rules that reference tables in different policies.
Previously, people could write rules that caused the datalog implementation
to enter an infinite loop by writing rules like a:p(x) :- b:p(x) and
b:p(x) :- a:p(x) (where each rule is in a different theory).

This change adds a safety check so that every time a rule is inserted
or deleted, that change is rejected if it would could cause an infinite
loop.  That check requires analyzing the combined dependency graph of
all of the policies.  Instead of re-computing the dependency graph
from scratch each time a rule is inserted into any policy, the
dependency graph of every theory is stored along with that theory
and updated every time the theory changes.

Unfortunately, the current implementation disallows recursion
even within a theory.  It is algorithmically non-obvious how
to appropriately relax this restriction.

Implements-blueprint: multiple-policies
Change-Id: I7a4a5235f9c64d1b73bd09cfa4de12fdeecd629a
Merge "Add safety check for cross-theory recursion"