Strengthen type safety

* ReadInstr<T> can only refer to ReadEvent<T>
* ReadInstr<T> can only publish operands as constant references
* Event objects cannot be instantiated directly
* WriteEvent<T> can only publish a constant reference to the read
  instruction from which it derives its value semantics

These changes create stronger type safety guarantees and make the
ownership of pointers more explicit.