У меня есть следующая программа, которая моделирует FIFO с процессом в Promela:свойство LTL и программа Promela
mtype = { PUSH, POP, IS_EMPTY, IS_FULL };
#define PRODUCER_UID 0
#define CONSUMER_UID 1
proctype fifo(chan inputs, outputs)
{
mtype command;
int data, tmp, src_uid;
bool data_valid = false;
do
:: true ->
inputs?command(tmp, src_uid);
if
:: command == PUSH ->
if
:: data_valid ->
outputs!IS_FULL(true, src_uid);
:: else ->
data = tmp
data_valid = true;
outputs!PUSH(data, src_uid);
fi
:: command == POP ->
if
:: !data_valid ->
outputs!IS_EMPTY(true, src_uid);
:: else ->
outputs!POP(data, src_uid);
data = -1;
data_valid = false;
fi
:: command == IS_EMPTY ->
outputs!IS_EMPTY(!data_valid, src_uid);
:: command == IS_FULL ->
outputs!IS_FULL(data_valid, src_uid);
fi;
od;
}
proctype producer(chan inputs, outputs)
{
mtype command;
int v;
do
:: true ->
atomic {
inputs!IS_FULL(false, PRODUCER_UID) ->
outputs?IS_FULL(v, PRODUCER_UID);
}
if
:: v == 1 ->
skip
:: else ->
select(v: 0..16);
printf("P[%d] - produced: %d\n", _pid, v);
access_fifo:
atomic {
inputs!PUSH(v, PRODUCER_UID);
outputs?command(v, PRODUCER_UID);
}
assert(command == PUSH);
fi;
od;
}
proctype consumer(chan inputs, outputs)
{
mtype command;
int v;
do
:: true ->
atomic {
inputs!IS_EMPTY(false, CONSUMER_UID) ->
outputs?IS_EMPTY(v, CONSUMER_UID);
}
if
:: v == 1 ->
skip
:: else ->
access_fifo:
atomic {
inputs!POP(v, CONSUMER_UID);
outputs?command(v, CONSUMER_UID);
}
assert(command == POP);
printf("P[%d] - consumed: %d\n", _pid, v);
fi;
od;
}
init {
chan inputs = [0] of { mtype, int, int };
chan outputs = [0] of { mtype, int, int };
run fifo(inputs, outputs); // pid: 1
run producer(inputs, outputs); // pid: 2
run consumer(inputs, outputs); // pid: 3
}
Я хочу добавить wr_ptr
и rd_ptr
в программе, чтобы указать, запись и чтения указателей относительно глубины FIFO при выполнении PUSH
обновления:
wr_ptr = wr_ptr % depth;
empty=0;
if
:: (rd_ptr == wr_ptr) -> full=true;
fi
и аналогичные возможности на POP
обновления
Не могли бы вы помочь мне добавить это в эту программу?
или должен ли я сделать его собственностью ltl и использовать его для проверки?
от комментариев: и я хочу, чтобы проверить это свойство, например, если ФИФО заполнен, один не должен иметь запрос на запись, что это правильный синтаксис полный означает, что ФИФО полно и wr_idx? является указателем записи, я не знаю, как получить доступ к полной, пустой, wr_idx, rd_idx, глубине процесса fifo в свойствах ltl fifo_no_write_when_full {[] (full ->! wr_idx)}
Есть ли способ поместить каждое значение, отправленное в fifo производителем в массиве этой программы? – lamia
Например, я хочу, чтобы глубина fifo равнялась 10, я делаю это в объявлении входов и выходов следующим образом: init { chan input = [10] of {mtype, int, int}; выходы chan = [10] из {mtype, int, int}; run fifo (входы, выходы); // pid: 1 запустить производителя (входы, выходы); // pid: 2 запустить потребитель (входы, выходы); // pid: 3 } – lamia