@startuml filter_sequence
actor Jules
participant Propagator
queue woke_up_constraints

participant constraint
participant var

Jules -> Propagator : Filter(startingVar)
Propagator -> woke_up_constraints : addItems( getConstraintsWithVar(startingVar))
loop woke_up_constraints is not empty
    Propagator -> woke_up_constraints : pop()
    return constraint

    Propagator -> constraint : filter(var_list, cardinality_list, removal_list, addition_list)
    note right
        Tous les filtrages à faire par rapport à <i>constraint</i> sont stockés
        dans les listes données en paramètre
    end note

    loop var_list != []
        Propagator -> Propagator : var = var_list.pop()

        Propagator -> Propagator : to_remove_from_upper = removal_list.pop()
        group for [val in to_remove_from_upper]
            Propagator -> var : remove_from_upper(val)
            return value_removed
            alt value_removed
                Propagator -> Propagator : list_variables_removal_pair.add((var,val))
            end
        end

        Propagator -> Propagator : to_add_to_lower = addition_list.pop()
        group for [val in to_add_to_lower]
            Propagator -> var : to_add_to_lower(val)
            return value_added
            alt value_removed
                Propagator -> Propagator : list_variables_addition_pair.add((var,val))
            end
        end

        Propagator -> Propagator : new_cardinal = cardinality_list.pop()
        alt new_cardinal != var.getCardinal()
            Propagator -> var : setCardinal(new_cardinal)
            Propagator -> Propagator : map_variables_cardinality_pair.put(var,new_cardinal)
            note right
                Cela fonctionne seulement si <i>new_cardinal</i>
                est meilleur ou égal au dernier changement de cardinal
                (en effet on remplace l'ancienne valeur dans la map)
            end note
        end
        Propagator -> var : is_valid()
        return failure_variable
        note right
            Cette variable booleene désigne si la variable
            ne peut être affecté à un ensemble.
        end note
        alt failure_variable
            Propagator -> Propagator : var_list.clear()
            Propagator -> woke_up_constraints : clear()
            Propagator -> Propagator : must_backtrack = true
        end
        alt is_filtered
            Propagator -> woke_up_constraints : addItems( getConstraintsWithVar(var))
            note right
                avec un <i>Set</i> comme structure woke_up_constraints
                On ne rajoute pas les contraintes déjà présentes
            end note
        end
    end
end
Propagator -> Propagator : stack_changes_variables.add(list_var_value_filtered)
Propagator -> Jules : must_backtrack
@enduml