Stable VariableDescriptor for TI-BASIC lists?

I’m developing a plugin for TI-BASIC, and I’m looking into integrating the DFA analysis engine into the language. I’m currently supporting some basic set of operations for the engine, such as storing values/other variables to variables. However, now I also want to support lists. Lists have no references, i.e. if I have a “L1→L2” it performs a deep copy of all the elements, rather than point to the same list structure. To achieve the analysis, I have a VariableDescriptor for the list itself and a VariableDescriptor for a list element. However, it seems that when I’m setting the list element of list 2, the list element of list 1 is joined with the new value.

So, in code terms, it looks like this:

1->L1(1)
2->L2(1)
L1(1)        <-- the analysis engine now says this could be 1 or 2

The ListElementDescriptor only stores the index, so 2 separate ListElementDescriptor’s are “equal”, but since they are always linked to the list qualifier (which is different for L1 and L2), I expect them to not overwrite each other.

Instruction wise, my control flow looks like this (temporary setup):

        // Add index 1 to list 1
        var list1 = factory.getVarFactory().createVariableValue(new ListDescriptor("L1"));
        addInstruction(new PushValueInstruction(fromValue(new BigDecimal("1"))));
        addInstruction(new SimpleAssignmentInstruction(null, factory.getVarFactory().createVariableValue(new ListElementDescriptor(1), list1)));
        addInstruction(new PopInstruction());

        // Add index 1 to list 2
        var list2 = factory.getVarFactory().createVariableValue(new ListDescriptor("L2"));
        addInstruction(new PushValueInstruction(fromValue(new BigDecimal("2"))));
        addInstruction(new SimpleAssignmentInstruction(null, factory.getVarFactory().createVariableValue(new ListElementDescriptor(1), list2)));
        addInstruction(new PopInstruction());

After interpreting this control flow with the default DfaMemoryStateImpl, the state looks like this:

<
  vars: [L1.[1]->[2, 1]] [L2.[1]->2] >

Both the ListDescriptor and the ListElementDescriptor are considered not stable, but if I set the ListDescriptor.isStable() to true, it works properly. But is that the right approach? It makes sense to not set the ListElementDescriptor as stable, since they can change normally. And would it work properly if I have a L1→L2 and then updating one of the elements of L1? Is there any way where using the SimpleAssignmentInstruction also copies all dependants from the qualifier to the new DfaVariableValue? Thanks in advance!

The full ListElementDescriptor:

public final class ListElementDescriptor implements VariableDescriptor {

    private final int index;

    public ListElementDescriptor(int index) {
        this.index = index;
    }

    public int getIndex() {
        return index;
    }

    @Override
    public boolean isStable() {
        return false;
    }

    @Override
    public @NotNull DfType getInitialDfType(@NotNull DfaVariableValue thisValue, @Nullable PsiElement context) {
        return DfType.TOP;
    }

    @Override
    public @NotNull DfType getDfType(@Nullable DfaVariableValue qualifier) {
        return DfType.TOP;
    }

    @Override
    public boolean equals(Object o) {
        if (o == this) return true;
        if (!(o instanceof ListElementDescriptor that)) return false;
        return that.index == this.index;
    }

    @Override
    public int hashCode() {
        return index + 12345678;
    }

    @Override
    public String toString() {
        return "[" + index + "]";
    }
}