Lay foundation for indirect memory access support

Recall that memory can be indirectly read or written though pointers.
The following changes strengthen the support for such indirect memory
accesses:

* Treat MemoryAddr as an opaque type
* Use Relation<uintptr_t, std::shared_ptr<Event>> class aggregation
* Add DeclVar<T[N]> template specialization
* Add WriteEvent<T>::is_direct()
* Add WriteEvent<T>::deref_instr_ref() for indirect memory writes
* Add Recorder::instr(...) function with dereference read instruction

Several other aspects require more work such as the initialization of
arrays from within the "main thread" and indirect memory accesses through
symbolic pointer offsets. For the latter we are investigating the
integration with a SMT array logic theory.