Einführung in JAM (Stefan Bosse) [5.2025] |
Die JavaScript Agent Machine (JAM) ist eine unievrsele Agentenausführungsplattform für AgentJS Agenten. Ein Agent gehört zu einer Klasse die durch eine Konstruktionsfunktion beschrieben wird. Diese muss vier wesentliche Abschnitte definieren:
this.x=<init>
this.act={ .. }
this.trans={ .. }
this.on
Die JAM Plattform ist als Shell in diese Übung integriert. Es wird keine weitere Software benötigt.
Weitere Informationen finden sich im über die JAM Shell in jamsh.pdf, über JAM in jam2020.pdf, und zusammenfassend in diesem Buch jamabx.pdf.
▸
|
✗
≡
|
Die Plattform beinhaltet u.A.:
▸
|
✗
|
Das Programmiermodell bildet das ATG Modell direkt ab:
this
Objekt, welches bei Lambda Ausdrücken so nicht anwendbar ist bzw. einen anderen Kontext hat.this
Objekts referenzieren, so auch den Zugriff auf Körpervariablen durchführen. this.next
Körpervariable geben die bei der Erzeugung eines Agentens die erste auszuführende Aktivität bezeichnet. Zur Laufzeit wird diese Variable die aktuell auszuführende Aktivität beinhalten.Zunächst muss grob der ATG definiert werden, d.h. die Aufgabe eines Agenten in Aktivitäten partitioniert werden. Es ist immer sinnvoll eine Start- und eine Endaktivität zu definieren.
myagent
definieren und mit dem ATG füllen. Der Name der Konstruktorfunktion entspricht der Agentenklasse (wird später noch benötigt). Am Ende wird die Funktion von JAM "übersetzt" und die Agentenklasse in JAM publiziert.
▸
|
✗
|
Körpervariablen müssen immer initialisiert werden (ggfs. mit null). Alle Aktivitäten (Namen) stehen als Variablen zur Verfügung. Alternativ kann man Aktivitäten durch einen String und deren Name bezeichnen. Die Übergangsfunktion definiert den Übergang von der aktuellen (links) bezeichneten Aktivität zu der nächsten. Wird null
oder udnefined
zurück gegeben findet kein Übergang statt.
▸
|
✗
|
Frage 1. Was geht schief bei der Ausführung unseres Agenten der den GGT berechnen soll und wie reagiert die Plattform? Finde den Fehler (recherchiere den GGt Algorithmus) und korrigiere obigen Agentencode. Es gibt noch einen weiteren Fehler im trans
Abschnitt. Korrigiere auch diesen so dass der Agent ein gültiges Ergebnis liefert.
compute
fehlt die Abfrage this.y==0
, was zu einer endlosen Ausführungsschleife compute → computer führt.Jetzt sollen zwei Agenten (mit zwei Agentenklassen) einmal als Konsument (Klient) und einmal als Produzent (Server) auftreten.
out(['GGT',10,20])
wird eine Anfrage an den Serveragenten gesendet;inp(['GGT',_,_], function (t) { .. })
wird die Anfrage im Serveragenten entgegen genommen;out(['GGT','RESULT',42])
wieder an den Klienten zurück gesendet, der mittels inp(['GGT',*RESULT',_],function (t) { .. }
auf das Ergebnis wartet.
Die Callback Funktion der inp
Funktion wird als Parameterargument entweder das vollständige Tupel als Array oder null enthalten (d.h. unterbrochen oder kein Tupel gefunden). Die Elemente können mit einem numerischen Index 0,1,2 usw. gelesen werden. Das formale Argument (Wildcard, Platzhalter) ist hier _
was null
entspricht. Eine Aktivität wird solange angehalten bis inp terminiert. Wichtig: Es darf pro Aktivität nur eine blockierende Funktion aufgerufen werden. Also kein zwei inp Funktionen in einer Aktivität aufrufen.
Aufgabe 2. Programmiere nachfolgend beide Agentenklassen und teste den Ablauf und das Zusammenspiel der Agenten.
▸
|
✗
|
VEJB
Wenn die Ausführung fehl schlägt können noch Tupel im Tupelraum verbleiben. Man kann statt out(..)
auch mark(timeout,..)
verwenden. Der Timeout kann auf 100 (ms) gesetzt werden. Oder jeder Agent entfernt alle Tupel die er aussenden würde (z.B. mit rm(['GGT',_,_],true)
.
▸
|
✗
|