A Joyce programozási nyelv

Utasítások

Statement =
EmptyStatement | AssignmentStatement |
AgentStatement | PortStatement |
InputOutputStatement | IfStatement |
WhileStatement | PollingStatement |
CompoundStatement .
EmptyStatement = .

Egy utasítás egy ágens által végrehajtandó akciót jelöl. Az üres utasítás az üres akciót jelöli.

Értékadó utasítás

AssignmentStatement = VariableAccess ":=" Expression .
A következő értékadó utasítás:
v:=e

Egy értéknek egy változóhoz való rendelést jelenti. A v változónak és az e kifejezésnek megegyező típusúnak kell lennie. Az értékadó utasítás három lépésben hajtódik végre:

  1. A v változó helyét meghatározza a program.
  2. e kiértékelésével kap egy értéket.
  3. Az így kapott értéket v-hez rendeli.
Példa

buf.contents[buf.head] := x

Ágenshívás

AgentStatement = AgentName [ "(" ActualParameterList ")" ] .
AgentParameterList = ActualParameter { "," ActualParameter } .
ActualParameter = Expression .

A következő ágenshívás
P(e1, e2, ..., em)

Egy új ágens aktiválását jelenti. P-nek egy ismert ágens eljárásnak kell lennie:
agent P(at:T1; a2:T2; ...; am:Tm);
var x1:U1; x2:U2; ...; xn:Un;
begin SL end;

Az
e1, e2, ..., em
aktuális paraméter listának a
a1:T1; a2:T2; ...; am:Tm
formális paraméter lista minden egyes ai formális paraméteréhez egy aktuális ei paramétert kell rendelnie. A sorrend, ahogyan a paraméter listában a paraméterek szerepelnek, egyértelműen meghatározza, hogy melyik formális paraméternek milyen aktuális érték felel meg. Az ei aktuális paraméter egy kifejezés, aminek a típusa meg kell, hogy egyezzen a megfelelő ai formális paraméter típusával.

Mikor egy ágens meghív egy új ágenst, az új ágens a következő két lépésben aktiválódik:

  1. Az új ágens saját változói a következőképpen jönnek létre:
    • Az a1, a2, ..., am paraméter listának megfelelően létrejönnek a formális paraméterek. Minden ai formális paraméterhez hozzárendelődik a megfelelő ei paraméter kiértékelésével kapott érték.
    • Létrejönnek az ágens törzsében definiált x1, x2, ..., xn változók határozatlan kezdőértékkel.
  2. Az új ágens elindul.
    Egy port operandus aktuális paraméterként használva az új ágens és a létrehozója számára is elérhető csatornát jelöl. Ez az új ágens számára egy ún. külső csatorna. Az ágens hívás végrehajtása után az új ágens és a létrehozó ágens párhuzamosan futnak tovább. Egy eljárás által definiált ágens rekurzívan aktiválhat egy ugyanazon eljárás által definiált új ágenset. Több ágens egyszerre aktiválhat ugyanazon eljárás által definiált ágenset. Minden egyes aktiválás egy saját változókkal rendelkező új ágenset hoz létre.

Példa
sort(succ, out)

Port utasítás

PortStatement = "+" PortAccess

Egy új csatorna létrehozását a csatorna aktiválásának nevezzük.
A következő port utasítás:
+c
egy új csatorna aktiválását jelöli. A c változónak egy ismert T port típusú változónak kell lennie.
Mikor egy ágens végrehajt egy port utasítást, egy új - a T típussal megadott ABC-jû - csatorna keletkezik, és a c port változóhoz egy erre a csatornára mutató pointer rendelődik. Az ágenset a csatorna létrehozójának, a csatornát az ágens belső csatornájának nevezzük. A csatorna megszűnik, ha a létrehozója terminál. Ezt a csatorna terminálásának nevezzük.

Példa

+inp

Input/output utasítások

InputP\OutputCommand = OutputCommand | InputCommand .
OutputCommand = PortAccess "!" OutputSymbol .
OutputSymbol = SymbolName [ "(" OutputExpression ")" ] .
OutputExpression = Expression .
InputCommand = PortAccess "?" InputSymbol .
InputSymol = SymbolName [ "(" InputVariable ")" ] .
InputVariable = VariableAccess .
InputOutputStatement = InputOutputCommand .

A kommunikáció egy szimbólum egyik ágenstől egy másik ágenshez csatornán keresztüli továbbítása. Az ágensek a csatornát lokális port változókon keresztül érik el. Képzeljünk el egy p ágenset, amely egy csatornát egy b port változón keresztül ér el, és egy q ágenset, amely ugyanezt a csatornát egy c port változón keresztül éri el. A port változóknak ugyanolyan típusúnak kell lenniük, esetünkben ez legyen:

T = [s1(T1), s2(T2), ..., sn(Tn)];

A következő output parancs:

b!si(ei)

azt jelenti, hogy a küldő ágens az si(ei) szimbólumot a b port változó által jelölt csatornán küldi keresztül. si-nek a T egyik szimbólum osztályának kell lennie, és az ei kifejezés típusa meg kell, hogy egyezzen a megfelelő Ti típussal.

A következő input parancs:

c?si(vi)

azt jelöli, hogy a fogadó ágens az si(vi) szimbólumot várja a c port változó által jelölt csatornán keresztül. si-nek a T egyik szimbólum osztályának kell lennie, és a v változó típusa meg kell egyezzen a megfelelő Ti típussal. Mikor egy p ágens az si szimbólumot egy csatornán keresztül szeretné küldeni, és egy másik q ágens ugyanezt a szimbólumot ugyanezen a csatornán keresztül várja, azt mondjuk, hogy ez a két ágens megfelel egymásnak, és a kommunikáció megvalósítható közöttük. Ha a kommunikáció megtörténik, a két ágens egyidejűleg végrehajtja az input és output parancsot. Ez az összetett esemény a következő lépések sorozatát jelenti:

  1. p kiértékeli az ei kifejezést.
  2. Az így kapott értéket q a vi változójához rendeli.
(Ha az si szimbólum egy jelzés, az 1 és 2 lépések üres akciót jelentenek.)

A kommunikáció után a kommunikáló ágensek párhuzamosan futnak tovább. Mikor egy ágens egy olyan input/output parancshoz ér, amelynek megfelelő kommunikáció nem megvalósítható, az ágens viselkedése attól függ, hogy a parancsot input/output utasításként, vagy polling utasításként (ld. később) használjuk. Egy input/output utasítás hatására az ágens felfüggesztődik, egészen addig, amíg az utasításnak megfelelő kommunikáció le nem zajlik. Egyszerre egy csatornán csak egy kommunikáció történhet. Egy csatorna két ágens között mindkét irányba tud szimbólumokat továbbítani. Egy csatornát kettő vagy több ágens használhat. Ha kettőnél több ágens szeretne ugyanazon a csatornán keresztül kommunikálni, többféleképpen is megfeleltethetőek egymásnak. Ilyenkor a csatorna tetszés szerint kiválaszt két egymásnak megfelelő ágenset, és közöttük bonyolítja le a kommunikációt. Az input/output parancs hatása definiálatlan, ha a port érték egy nem létező csatornát jelent.

Példák
inp?eos
succ!int(x)

If utasítás

IfStatement = "if" BooleanExpression "then" Statement ["else" Statement] .
BooleanExpression = Expression .

A következő if utasítás:

if B then S1 else S2

Az S1 és S2 utasítás közül pontosan az egyiknek a végrehajtását jelenti. A B kifejezésnek logikai típusúnak kell lennie.

Az if utasítás két lépésben hajtódik végre:

  1. A B kifejezés kiértékelésével kapunk egy logikai értéket.
  2. Ha ez az érték igaz, S1 hajtódik végre; különben S2 hajtódik végre. (Ha S2-t elhagyjuk, akkor semmi sem történik.)

Példák
if succ <> none then out!eos
if x>y then begin succ!int(x); x := y end else succ!int(y)

While utasítás

WhileStatement = "while" BooleanExpression "do" Statement .

A következő while utasítás:
while B do S

Az S utasítás nulla vagy több végrehajtását jelöli. A B kifejezésnek logikai típusúnak kell lennie.

A while utasítás a következő lépésekben hajtódik végre:

  1. 1. A B kifejezés kiértékelésével kapunk egy logikai értéket.
  2. 2. Ha ez az érték igaz, az S végrehajtódik, és utána az 1. és 2. Lépések megismétlődnek, különben a while utasítás végrehajtása véget ér.

Példa
while i<=n do begin io?readint(x); inp!(x); i := i + 1 end

Polling utasítás

PollingStatement = "poll" GuardedStatementList "end" .
GuardedStatementList = GuardedStatement { "|" GuardedStatement } .
GuardedStatement = Guard "->" StatementList .
Guard = PollingCommand [ "&" PollingExpression ] .
PolingCommand = InputOutputCommand .
PollingExpression = BooleanExpression .

A következő polling utasítás:
poll
C1 & B1 -> SL1 |
C2 & B2 -> SL2 |
...
Cn & Bn -> SLn
end
a

Ci & Bi -> SLi

Az őrfeltétellel ellátott utasítások közül pontosan egynek a végrehajtását jelenti.

Egy ágens egy polling utasítást két fázisban hajt végre, ezek: a választási és a befejezési fázis:

    Választás: az ágens ciklikusan megvizsgálja a C1 & B1, C2 & B2, ..., Cn & Bn őrfeltételeket, egészen addig, amíg egy olyan Ci polling parancsot nem talál, amelynek megfelelő kommunikáció megvalósítható, és amelynek Bi feltétele igaz (vagy hiányzik). Befejezés: az ágens végrehajtja az így kiválasztott Ci polling parancsot, majd végrehajtja a megfelelő SLi utasításokat.

Miközben egy ágens az 1. fázisban van, csak olyan ágens felel meg neki, amely input/output utasítást szeretne végrehajtani. Két olyan ágens, amely a választás fázisában van, nem felel meg egymásnak.

Példa
poll user?P & x > 0 -> x:= x - 1 | user?V -> x:= x + 1 end

Az összetett utasítás

CompoundStatement = "begin" StatementList "end" .
StatementList = Statement { ";" Statement } .

A következõ összetett utasítás
begin SL end

az SL utasításlista végrehajtását jelenti.

Az S1; S2; ...; Sn utasításlista végrehajtása azt jelenti, hogy az S1, S2, ..., Sn utasítások egymás után a leírt sorrendben végrehajtódnak.

Példa

begin succ!int(x); x := y end<