= Thoughts on references = Create interfaces: * `ReferenceExpression extends SymbolicExpression` * `NTReferenceExpression extends ReferenceExpression` for non-trivial references, i.e., references to a tuple component, array element, or union member, or an "offset reference" * `ArrayElementReference extends NTReferenceExpression` * `TupleComponentReference extends NTReferenceExpression` * `UnionMemberReference extends NTReferenceExpression` * `OffsetReference extends NTReferenceExpression` Interface: The following methods can go in `ReferenceExpression`: {{{ /** Is this the null reference? */ boolean isNullReference(); /** Is this the identity reference? */ boolean isIdentityReference(); /** Is this an array element reference? */ boolean isArrayElementReference(); /** Is this a tuple component reference? */ boolean isTupleComponentReference(); /** Is this a union element reference? */ boolean isUnionMemberReference(); /** Is this an "offset reference" ? */ boolean isOffsetReference(); }}} The following methods can go in `NTReferenceExpression`: {{{ /** As this is a reference to an array element, tuple component, union member, * or an offset reference, returns the reference to the parent, * i.e., the array, tuple, union, or the other reference, resp. ReferenceExpression getParent(); }}} In `ArrayElementReference`: {{{ NumericExpression getIndex(); }}} In `TupleComponentReference`: {{{ IntObject getIndex(); }}} In `UnionMemberReference`: {{{ IntObject getIndex(); }}} In `OffsetReference`: {{{ NumericExpression getOffset(); }}} The following can go in `SymbolicUniverse`: {{{ /** Returns the type of all reference expressions. */ SymbolicType referenceType(); /** Returns the "null reference", a symbolic expression of reference type which is * not equal to a reference value returned by * any of the other methods, and which cannot be dereferenced. */ ReferenceExpression nullReference(); /** Given a reference and a value, returns the sub-expression of value specified by the reference. * Throws exception if the reference is not of the correct form for the type of value. */ SymbolicExpression dereference(SymbolicExpression value, ReferenceExpression reference); /** Returns the identity (or "trivial") reference I. This is the reference characterized by the * property that dereference(I,v) returns v for any symbolic expression v. */ ReferenceExpression identityReference(); /** Given a reference to an array and an index (integer), returns a reference to the element of the array * at that index */ ArrayElementReference arrayElementReference(ReferenceExpression arrayReference, NumericExpression index); /** Given a reference to a tuple, and a field index, returns a reference to that component of the tuple */ TupleComponentReference tupleComponentReference(ReferenceExpression tupleReference, IntObject fieldIndex); /** Given a reference to a union (expression of union type) and an index of a member type of that union, returns * a reference to the underlying element */ UnionMemberReference unionElementReference(ReferenceExpression unionReference, IntObject memberIndex); OffsetReference offsetReference(ReferenceExpression reference, NumericExpression offset); /** Given a symbolic expression value, a reference to a point within that value, and a subValue, returns * the symbolic expression obtained by replacing the referenced part of value with subValue. */ SymbolicExpression assign(SymbolicExpression value, ReferenceExpression reference, SymbolicExpression subValue); }}}