Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lectures / lecture12.ppt
Скачиваний:
8
Добавлен:
06.06.2015
Размер:
286.72 Кб
Скачать

else if (AuthPathBillingReply(ID j, bool ответ))

{СИТ ! AuthPathReply(ответ); if (se.stop) #stop;

if (ответ) $sCall else if (se.outgoing) $sAuthNumPath else #stop

}

else if (AuthOutgoingBillingReply(ID j, bool ответ)) { СИТ ! AuthOutgoingReply(ответ);

if (se.stop) #stop; if (ответ) $sAuthNumPath else $sKey

}

else if (Key(ID j))

{БС ! KeyBilling(ID j); $sKeyBilling } else if (KeyBillingReply(bool ответ))

{СИТ ! KeyReply(ответ);

if (se.stop) #stop; if ( ответ) $sKey else $sAuthNumPath

}

else if (Stop(ID j))

if (se.state in {sAuthNum, sCall, sKey, sAuthNumPath}) #stop else se.stop = true

else if (AuthNum(ID j))

{БС ! AuthNumBilling(); $sAuthNumBilling } else if (AuthPath(ID j))

{БС ! AuthPathBilling(); $sAuthPathBilling }

else if (StartCall(ID j)) $sStartCall;

else if (StartTalk(ID j)) $sTalk

else if (StopTalk(ID j)) $sStopTalk;

else if (StopCall(ID j)) { БС ! CallBilling(); if (se.stop) #stop

else if (se.outgoing) $sAuthNumPath else #stop

};

stop: БС ! StopBiling(); удалитьСеанс(se.id) #loop

}

Реализация для ненадежных каналов

Особенности ненадежных каналов: потеря, дублирование, изменение порядка сообщений

Цепочки следования сообщений:

AuthIncomingPath {StartCal, StartTalk, StopTalk, StopCall, Stop} AuthIncoming AuthPath {StartCal, StartTalk, StopTalk, StopCall, Stop}

AuthOutgoing Key AuthNum AuthPath {StartCal, StartTalk, StopTalk, StopCall, Stop}

Спецификация процесса сеансЗвонка меняется !

В четверке сообщений StartCal, StartTalk, StopTalk, StopCall значимыми являются только StopTalk и StopCall.

Используется таймер, чтобы избежать дедлок в случае потери сообщений

Сообщения, относящиеся к предыдущему звонку, могут прийти при обработке очередного звонка необходимо уметь распознавать принадлежность сообщения звонку в случае серии звонков в одном сеансе хранить информацию о всех звонках серии

Stop() завершает сеанс лишь в случае завершения сеанса звонка (получения StopCall)

Изменившаяся часть реализации радиус-сервера

else if (AuthNumBillingReply(ID j, bool ответ)) { СИТ ! AuthNumReply(ответ);

if (se.stop) if (se.completedAll()) #stop else SetTimeout() else if ( ответ) if (se.outgoing) $sAuthNumPath else #stop else if (se.outgoing se.incomingPath) $sAuthNum

else { БС ! AuthPathBilling(); $sAuthPathBilling }

}

else if (Stop())

if (se.state = sKey) #stop else se.stop = true else if (StopTalk() StopCall())

if ( (se.stop se.outgoing) & se.completedAll() ) { БС ! CallBilling(); #stop }

Почти все специальные внутренние состояния становятся ненужными

Процессорная спецификация языка исчисления вычислимых предикатов

Процессорная спецификация описывает

функционирование процессора языка программирования.

Операционная семантика языка исчисления вычислимых предикатов, определяемая предикатной программой исполнения программы на языке исчисления

Кодирование программы и данных

type NAME;

// множество всевозможных имен

 

type TYPE;

// множество произвольных типов

 

type VAR = struct NAME name, TYPE type end;

// переменная

type SVAR = seq VAR;

// список переменных

 

type PREDNAMES = set NAME; // набор имен предикатов программы type Program(PREDNAMES predNames) = array predNames of PredicateDef; type PredicateDef = struct SVAR in, out, local, RIGHT right end;

type RIGHT =

 

 

union

 

 

super:

CALL fst, snd | // суперпозиция fst; snd

paral:

CALL fst, snd | // параллельная композиция fst || snd

alter:

VAR cond, CALL then, else |

 

 

// if cond then then else else end

gen:

NAME predName, SVAR in1, in2, out |

 

// lambda(in2: out) predName(in1, in2: out)

appl:

NAME predName, SVAR in, out |

// predName(in: out)

arrcons:

VAR arr, NAME predName, range, SVAR in2, rangepars |

base:

// forAll i range(rangepars) do arr[i] = predName(i, in2) end

// базисный предикат исчисления

end;

 

 

type CALL = struct NAME predName, SVAR in, out end; // вызов предиката

type VALUE;

// значение произвольного типа

type SVALUE = seq VALUE;

// список значений

type QNAME = set NAME;

 

type SECT(QNAME sn) = array sn of VALUE; // секция памяти

type ID;

// генеральное множество имен секций

type SID = set ID;

// тип подмножества имен секций

type MEMORY(SID sip) = array sip of SECT; // память программы

Операции над секциями

newSect(SVAR q: SECT s, ID id)

id sip & profileSect(q: s) & sip’ = sip + id & mem’ = mem + (id: s); val(SECT s, VAR x: VALUE v) v = s[x];

assign(SECT s, VAR x, VALUE v: SECT s’) s[x] := v s’ = s(x: v); multival(SECT s, SVAR z: SVALUE w) w = s[z]

if z = nil then w = nil else w = s[head(z)] + multival(s, tail(z)) end; multiassign(SECT s, SVAR z, SVALUE w: SECT s’) s[z] := w

if z = nil then s’ = s

else multiassign(s(head(z): head(w)), tail(z), tail(w): s’) end;

delSect(ID id: ) id sip sip’ = sip - id & mem’= mem[sip’];

Исполнение программы

Program prog; PREDNAMES predNames;

runProgram(NAME startPred, SVALUE pars: SVAR results) startPred predNames {

PredicateDef p = prog[startPred]; newSect(p.in + p.out: SECT s, ID id); s[p.in] := pars;

runCall(s, startPred, p.in, p.out); results:= s[p.out];

};

Исполнение вызова предиката

runCall(SECT sext, NAME predName, SVAR in, SVAR out) predName predNames {

PredicateDef p = prog[startPred]; newSect(p.in + p.out + p.local: SECT s, ID id); s[p.in] := sext[in];

runRirht(s, p.right); sext[out] := s[p.out]; delSect(id)

};

runRight(SECT s, RIGHT right) {

 

case right of

 

 

super:

runSuper(SECT s, CALL fst, snd)

|

paral:

runParal(SECT s, CALL fst, snd)

|

alter:

runIf(SECT s, VAR cond, CALL then, else)

|

gen:

runLambda(SECT s, NAME predName, SVAR in1, in2, out) |

 

// lambda(in2: out) predName(in1, in2: out)

appl:

 

 

 

runApplPred(SECT s, NAME predName, SVAR in, out) |

arrcons:

runForAll(SECT s, VAR arr, NAME predName, range,

 

 

 

SVAR in2, rangepars) |

base:

// forAll i range(rangepars) do arr[i] = predName(i, in2) end

runBasePred(SECT s) // базисный предикат исчисления

end

 

 

 

};

Исполнение суперпозиции runSuper(SECT s, CALL fst, snd) {

runCall(s, fst.predName, fst.in, fst.out); runCall(s, snd.predName, snd.in, snd.out);

};

Исполнение параллельной композиции

runParal(SECT s, CALL fst, snd) {

runCall(s, fst.predName, fst.in, fst.out) || runCall(s, snd.predName, snd.in, snd.out);

};

Исполнение условного оператора

runIf(SECT s, VAR cond, CALL then, else) {

if s[cond] then runCall(s, then.predName, then.in, then.out) else runCall(s, else.predName, else.in, else.out) end

};

Соседние файлы в папке lectures