Как вы обнаружили, собственный механизм фильтрации, предлагаемый Spin
, способен только фильтровать по значению и, более конкретно, он не может фильтровать по выражению .
Может показаться, что это не идеальное решение, но самый простой подход заключается в оценке булева выражения, связанного с условием фильтрации, перед отправкой сообщения.
Пример:
chan c = [42] of { int, bool };
proctype Test()
{
int value;
do
:: atomic {
c??[value, true] ->
c??value, true; // true: filter messages larger than 5
printf("Popped: %d\n", value);
}
:: else ->
printf("No more messages larger than 5.\n");
break;
od;
bool cond;
printf("\nDischarging Channel..\n");
do
:: c?[value, cond] ->
c?value, cond;
printf("Popped: %d\n", value);
:: else ->
break;
od;
}
init {
int i;
for (i : 1 .. 10) {
c!i(i >= 5) // evaluate filtering condition when message is sent
}
run Test();
}
Вывод:
~$ spin test.pml
Popped: 5
Popped: 6
Popped: 7
Popped: 8
Popped: 9
Popped: 10
No more messages larger than 5.
Discharging Channel..
Popped: 1
Popped: 2
Popped: 3
Popped: 4
2 processes created
Я признаю, что это не совсеммасштабируемый подход, но Я не мог придумать никакого другого решения .