Question
Implement an insertion-ordered mutable set whose iterators observe a stable snapshot even as the live set changes.
```python
class SnapshotSet:
def __init__(self, items=None): ...
def add(self, value) -> None: ...
def remove(self, value) -> None: ...
def contains(self, value) -> bool: ...
def iterator(self): ...
class SnapshotIterator:
def has_next(self) -> bool: ...
def next(self): ...
```
## Requirements
- Iteration follows current insertion order at iterator creation time.
- Adding an already-present value changes nothing.
- Removing and later re-adding a value places it at the end of the live order.
- `contains` reflects current state, while an existing iterator continues to return exactly its snapshot.
- `next` raises `StopIteration` after exhaustion.
- Removing an absent value is a no-op. `has_next` never advances an iterator, including repeated checks after exhaustion. Independent iterators have independent cursors.
- Inputs are finite sequences of hashable values with stable equality/hash behavior. Snapshot isolation concerns membership and order, not a deep copy of each value object. Construction consumes the initial sequence; later changes to the caller's list do not change the set.
- The provided `run_case` drives membership fixtures and version-one snapshot operation traces. It assigns fixture-local iterator IDs, calls your iterator methods, and translates `StopIteration` into a JSON exhaustion marker. Implement both classes and all listed methods, not the driver. Snapshot fixtures test retained iterators after mutation as well as fresh live order.
- Explain the time and memory cost of snapshot creation and mutation.
## Design discussion (not graded)
1. Avoid copying all values for every iterator by using versioned membership intervals.
2. Reclaim historical versions when iterators finish.
3. Make mutation and iteration thread-safe.
4. Persist snapshots or expose a stable snapshot ID.