{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# PythonPDEVS examples" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import PythonPDEVS modelling elements for *AtomicDEVS* and *CoupledDEVS* models.\n", "Also import the concept of *INFINITY* to be used." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from pypdevs.DEVS import AtomicDEVS, CoupledDEVS\n", "from pypdevs.infinity import INFINITY" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create some simple *AtomicDEVS* models for a *Generator* and a *Queue*." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "class Generator(AtomicDEVS):\n", " def __init__(self):\n", " AtomicDEVS.__init__(self, \"Generator\")\n", " self.state = 0\n", " self.outport = self.addOutPort(\"outport\")\n", "\n", " def timeAdvance(self):\n", " return 1.0\n", "\n", " def outputFnc(self):\n", " # Our message is simply the integer 5, though this could be anything\n", " return {self.outport: 5}\n", "\n", " def intTransition(self):\n", " return self.state + 1" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class Queue(AtomicDEVS):\n", " def __init__(self):\n", " AtomicDEVS.__init__(self, \"Queue\")\n", " self.state = None\n", " self.processing_time = 1.0\n", " self.inport = self.addInPort(\"input\")\n", " self.outport = self.addOutPort(\"output\")\n", "\n", " def timeAdvance(self):\n", " if self.state is None:\n", " return INFINITY\n", " else:\n", " return self.processing_time\n", "\n", " def outputFnc(self):\n", " return {self.outport: self.state}\n", "\n", " def extTransition(self, inputs):\n", " self.state = inputs[self.inport]\n", " return self.state\n", "\n", " def intTransition(self):\n", " return None" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Add the Coupled DEVS model for a simple *CoupledQueue*." ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "class CQueue(CoupledDEVS):\n", " def __init__(self):\n", " CoupledDEVS.__init__(self, \"CQueue\")\n", " self.generator = self.addSubModel(Generator())\n", " self.queue = self.addSubModel(Queue())\n", " self.connectPorts(self.generator.outport, self.queue.inport)\n", " \n", " def select(self, imm):\n", " return self.queue" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally run the simulation by setting up an experiment file as follows.\n", "First, however, we have to include the simulator concept." ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from pypdevs.simulator import Simulator" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "ename": "TypeError", "evalue": "unorderable types: Queue() < Generator()", "output_type": "error", "traceback": [ "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0msim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetClassicDEVS\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0msim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msetTerminationTime\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10.0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 6\u001b[0;31m \u001b[0msim\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/simulator.py\u001b[0m in \u001b[0;36msimulate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 612\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheckpoint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 613\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 614\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreal_simulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 615\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 616\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mremoveTracers\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/simulator.py\u001b[0m in \u001b[0;36mreal_simulate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 729\u001b[0m \u001b[0;31m# Simply do a blocking call, thus preventing the finish ring algorithm\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 730\u001b[0m \u001b[0;31m#begin = time.time()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 731\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcontroller\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mgetProxy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlocations\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate_sync\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 732\u001b[0m \u001b[0;31m#print(time.time() - begin)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 733\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/MPIRedirect.py\u001b[0m in \u001b[0;36mlocalcall\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 224\u001b[0m \u001b[0mA\u001b[0m \u001b[0mcall\u001b[0m \u001b[0mto\u001b[0m \u001b[0ma\u001b[0m \u001b[0mlocal\u001b[0m \u001b[0mlocation\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 225\u001b[0m \"\"\"\n\u001b[0;32m--> 226\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mLocalRedirect\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mlocalCall\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 227\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mlocalcall\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 228\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/MPIRedirect.py\u001b[0m in \u001b[0;36mlocalCall\u001b[0;34m(self, method, *args, **kwargs)\u001b[0m\n\u001b[1;32m 200\u001b[0m \u001b[0mthreading\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mThread\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtarget\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mfunc\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkwargs\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mstart\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 201\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 202\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 203\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 204\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0m__init__\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mserver\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/controller.py\u001b[0m in \u001b[0;36msimulate_sync\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 172\u001b[0m \u001b[0mSynchronous\u001b[0m \u001b[0msimulation\u001b[0m \u001b[0mcall\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0midentical\u001b[0m \u001b[0mto\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mnormal\u001b[0m \u001b[0mcall\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mthe\u001b[0m \u001b[0mexception\u001b[0m \u001b[0mthat\u001b[0m \u001b[0mit\u001b[0m \u001b[0mwill\u001b[0m \u001b[0mbe\u001b[0m \u001b[0ma\u001b[0m \u001b[0mblocking\u001b[0m \u001b[0mcall\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0monly\u001b[0m \u001b[0;34m\"simulate\"\u001b[0m \u001b[0;32mis\u001b[0m \u001b[0mmarked\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0moneway\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 173\u001b[0m \"\"\"\n\u001b[0;32m--> 174\u001b[0;31m \u001b[0mBaseSimulator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate_sync\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 175\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mno_finish_ring\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0macquire\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 176\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/basesimulator.py\u001b[0m in \u001b[0;36msimulate_sync\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1299\u001b[0m \u001b[0mA\u001b[0m \u001b[0msmall\u001b[0m \u001b[0mwrapper\u001b[0m \u001b[0maround\u001b[0m \u001b[0mthe\u001b[0m \u001b[0msimulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0mfunction\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mthough\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0ma\u001b[0m \u001b[0mdifferent\u001b[0m \u001b[0mname\u001b[0m \u001b[0mto\u001b[0m \u001b[0mallow\u001b[0m \u001b[0ma\u001b[0m \u001b[0mmuch\u001b[0m \u001b[0msimpler\u001b[0m \u001b[0mMPI\u001b[0m \u001b[0mone\u001b[0m \u001b[0mway\u001b[0m \u001b[0mcheck\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1300\u001b[0m \"\"\"\n\u001b[0;32m-> 1301\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1302\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1303\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0msimulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/controller.py\u001b[0m in \u001b[0;36msimulate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 185\u001b[0m \u001b[0mvisualizeLocations\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 186\u001b[0m \u001b[0;31m# Call superclass (the actual simulation)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 187\u001b[0;31m \u001b[0mBaseSimulator\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimulate\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 188\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprev_termination_time\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtermination_time\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 189\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/basesimulator.py\u001b[0m in \u001b[0;36msimulate\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1328\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1329\u001b[0m \u001b[0;32mwhile\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1330\u001b[0;31m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrunsim\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1331\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mirreversible\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1332\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mshould_run\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mclear\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/basesimulator.py\u001b[0m in \u001b[0;36mrunsim\u001b[0;34m(self)\u001b[0m\n\u001b[1;32m 1168\u001b[0m \u001b[0;31m# Don't interrupt the output generation, as these nodes WILL be marked as 'sent'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1169\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mVlock\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1170\u001b[0;31m \u001b[0mreschedule\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcoupledOutputGeneration\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_clock\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1171\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1172\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmassAtomicTransitions\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtransitioning\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcurrent_clock\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;32m~/.local/lib64/python3.5/site-packages/pypdevs/solver.py\u001b[0m in \u001b[0;36mcoupledOutputGenerationClassic\u001b[0;34m(self, time)\u001b[0m\n\u001b[1;32m 256\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimminent\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m>\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 257\u001b[0m \u001b[0;31m# Perform all selects\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 258\u001b[0;31m \u001b[0mimminent\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msort\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 259\u001b[0m \u001b[0mpending\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mimminent\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 260\u001b[0m \u001b[0mlevel\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", "\u001b[0;31mTypeError\u001b[0m: unorderable types: Queue() < Generator()" ] } ], "source": [ "model = CQueue()\n", "sim = Simulator(model)\n", "# Required to set Classic DEVS, as we simulate in Parallel DEVS otherwise\n", "sim.setClassicDEVS()\n", "sim.setTerminationTime(10.0)\n", "sim.simulate()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Simulation is now done, and the results can be seen in the changed states of the model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model.generator.state" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another option is to use verbose simulation, as follows." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = CQueue()\n", "sim = Simulator(model)\n", "sim.setVerbose()\n", "# Required to set Classic DEVS, as we simulate in Parallel DEVS otherwise\n", "sim.setClassicDEVS()\n", "sim.setTerminationTime(10.0)\n", "sim.simulate()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Apart from Classic DEVS simulation, Parallel DEVS simulation is also possible.bag\n", "For this, we add a slightly altered version of the models, to comply with bag semantics." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class Generator(AtomicDEVS):\n", " def __init__(self):\n", " AtomicDEVS.__init__(self, \"Generator\")\n", " self.state = 0\n", " self.outport = self.addOutPort(\"outport\")\n", "\n", " def timeAdvance(self):\n", " return 1.0\n", "\n", " def outputFnc(self):\n", " # Our message is simply the integer 5, though this could be anything\n", " return {self.outport: [5]}\n", "\n", " def intTransition(self):\n", " return self.state + 1\n", " \n", "class Queue(AtomicDEVS):\n", " def __init__(self):\n", " AtomicDEVS.__init__(self, \"Queue\")\n", " self.state = None\n", " self.processing_time = 1.0\n", " self.inport = self.addInPort(\"input\")\n", " self.outport = self.addOutPort(\"output\")\n", "\n", " def timeAdvance(self):\n", " if self.state is None:\n", " return INFINITY\n", " else:\n", " return self.processing_time\n", "\n", " def outputFnc(self):\n", " return {self.outport: [self.state]}\n", "\n", " def extTransition(self, inputs):\n", " self.state = inputs[self.inport][0]\n", " return self.state\n", "\n", " def intTransition(self):\n", " self.state = None\n", " return self.state" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And similar to before, we start the experiment, now not using the *setClassicDEVS* option." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = CQueue()\n", "sim = Simulator(model)\n", "sim.setVerbose()\n", "sim.setTerminationTime(10.0)\n", "sim.simulate()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A termination condition can also be used." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def termFunc(clock, model):\n", " if model.generator.state > 5:\n", " # The generator has generated more than 5 events\n", " # So stop\n", " return True\n", " elif clock[0] > 10:\n", " # Or if the clock has progressed past simulation time 10\n", " return True\n", " else:\n", " # Otherwise, we simply continue\n", " return False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = CQueue()\n", "sim = Simulator(model)\n", "sim.setVerbose()\n", "sim.setTerminationCondition(termFunc)\n", "sim.simulate()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.5.5" } }, "nbformat": 4, "nbformat_minor": 2 }