Add symbolic data race detector for release-acquire programs

A memory::SymbolicProgram and its operators should be seen as a
domain-specific language (DSL) which can be used to specify the
sequenced-before relation of concurrent programs that can read and
write shared memory with release-acquire or non-synchronizing
load and store instructions.

The rationale behind this approach is that there are many flavours
of release-acquire semantics. Rather than committing ourselves to
one flavour, the DSL features sequential and concurrent operators
with which a programming language designer may explore the design
space by translating a sequence of instructions in one language to
our DSL which is more low-level but truly concurrent.