Oldest-first immutable sequence of guard conjuncts with O(1) copy.
Replaces the flat std::vector<expr2tc> that guard2tc used to hold. The vector was deep-copied on every guard copy (O(N) element copies plus N refcount bumps on the conjuncts) and rebuilt from scratch on every set operation, giving the Θ(N²) blow-up at deep loop unwinding.
Backed by immer::vector, a persistent (structurally-shared) bit-mapped vector trie. Conjuncts stay oldest-first — the same canonical order as guard2tc's cached left-leaning and-chain, so the index correspondence the prefix/diff logic relies on is preserved exactly.
Costs: copy O(1) (shared root); push_back / index O(log32 N) ≈ O(1) for the few-hundred-element guards symex builds; prefix (take) shares subtrees; iterate O(N). We use immer::vector rather than flex_vector (the relaxed RRB tree): flex's only edge is O(log N) drop()/suffix slicing, but measured max suffix length in real symex is 1 (guards diverge one conjunct at a time at merge points), so flex's relaxed-radix bookkeeping is pure overhead. A/B: immer::vector was ~5% fewer instructions and ~15% faster symex on test_locks_13, same verdicts. suffix() rebuilds [n,size) since plain vector has no drop(); that is O(suffix) but suffix is ~1 in practice.
Ownership: NON-atomic refcount, no lock (unsafe_refcount_policy + no_lock_policy). Guards are thread-confined — the only symex parallelism (--parallel-solving) forks threads to solve an already-built equation, while the guard set-algebra runs in the single-threaded symex phase, and the conjunct list is never stored in the equation (only the expr2tc base is, and that is an atomic irep_container). So a non-atomic refcount is sound. NOTE: this is load-bearing on "symex is not parallelized" — if that ever changes, switch to refcount_policy (atomic; measured ~10-15% slower here, not the 2× the value-returning accessors below cost). immer's default policy additionally pairs the atomic refcount with spinlock_policy (a test_and_set lock around every tree op for the transient API); we never share transients across threads, so no_lock is used regardless of refcount choice.