eval reduces both sides and compares them when both are concrete. Numeric equality is tolerance-based, tied to env.precision -- exact Double comparison would make sin(pi) = 0 false on floating-point noise; instead two numbers are equal when |a - b| <= 0.5 * 10^(-p). Concrete matrices compare element-wise under the same tolerance. Anything else stays symbolic with the sides reduced.
Marked _ElementWise: an equation is a container of its two sides, so derive/simplify/expand/integrate apply the algorithm to both sides (e.g. d/dx (lhs = rhs) is d(lhs)/dx = d(rhs)/dx).
toString is "lhs = rhs" (no outer parentheses): equations exist only at the top level of the grammar, and the round-trip invariant parse(toString(e)) == e holds.