process_patterns_library.mvc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491
  1. AtomicDEVSBlock Initial {
  2. name = "Initial"
  3. initialState = """
  4. self.state, self.elapsed = True, 0.0
  5. """
  6. timeAdvance = """
  7. if self.state:
  8. return 0.0
  9. else:
  10. return float('inf')
  11. """
  12. outputFnc = """
  13. return {self.my_ports['control_out']: {}}
  14. """
  15. intTransition = """
  16. return False
  17. """
  18. extTransition = """
  19. return None
  20. """
  21. }
  22. OutputPort init_co {
  23. name = "control_out"
  24. }
  25. DEVSBlockToPort (Initial, init_co) {}
  26. AtomicDEVSBlock Finish {
  27. name = "Finish"
  28. initialState = """
  29. self.state, self.elapsed = None, 0.0
  30. """
  31. timeAdvance = """
  32. return float('inf')
  33. """
  34. outputFnc = """
  35. return {}
  36. """
  37. intTransition = """
  38. return None
  39. """
  40. extTransition = """
  41. return self.elapsed
  42. """
  43. }
  44. InputPort finish_ci {
  45. name = "control_in"
  46. }
  47. DEVSBlockToPort (Finish, finish_ci) {}
  48. AtomicDEVSBlock ResourceHandler {
  49. name = "ResourceHandler"
  50. initialState = """
  51. self.state, self.elapsed = {'resources': self.parameters[0], 'queue': []}, 0.0
  52. """
  53. timeAdvance = """
  54. if self.state['queue'] and self.state['resources']:
  55. # Can grant a resource
  56. return 0.0
  57. else:
  58. # No request queued, or no available resources to handle the request
  59. return float('inf')
  60. """
  61. outputFnc = """
  62. return {self.my_ports['resource_out']: {'id': self.state['queue'][0]}}
  63. """
  64. intTransition = """
  65. # Processed a request that could be processed
  66. self.state['resources'] -= 1
  67. del self.state['queue'][0]
  68. return self.state
  69. """
  70. extTransition = """
  71. for inp in inputs[self.my_ports['resource_in']]:
  72. if inp['type'] == 'request':
  73. # Queue the request
  74. self.state['queue'].append(inp['id'])
  75. elif inp['type'] == 'release':
  76. # Increment the number of available resources
  77. self.state['resources'] += 1
  78. return self.state
  79. """
  80. }
  81. InputPort rh_ri {
  82. name = "resource_in"
  83. }
  84. OutputPort rh_ro {
  85. name = "resource_out"
  86. }
  87. DEVSBlockToPort (ResourceHandler, rh_ri) {}
  88. DEVSBlockToPort (ResourceHandler, rh_ro) {}
  89. AtomicDEVSBlock Activity {
  90. name = "Activity"
  91. initialState = """
  92. class ActivityState(object):
  93. def __init__(self, name, distribution):
  94. self.timer = float('inf')
  95. self.mode = 'inactive'
  96. self.counter = 0
  97. self.name = name
  98. self.distribution = distribution
  99. def __str__(self):
  100. return str(vars(self))
  101. def random_sample(self):
  102. return self.distribution(self.counter)
  103. self.state, self.elapsed = ActivityState(self.parameters[0], self.parameters[1]), 0.0
  104. """
  105. timeAdvance = """
  106. return self.state.timer
  107. """
  108. outputFnc = """
  109. if self.state.mode == 'active':
  110. # Output the control token to the next model in line, and release the resources
  111. return {self.my_ports['control_out']: {}, self.my_ports['resource_out']: [{'type': 'release'}]}
  112. elif self.state.mode == 'request_resource':
  113. # Output a request for resources with a specified ID (used to find out whether this was our request)
  114. return {self.my_ports['resource_out']: [{'type': 'request', 'id': '%s-%s' % (self.state.name, self.state.counter)}]}
  115. else:
  116. return {}
  117. """
  118. intTransition = """
  119. self.state.timer -= self.timeAdvance()
  120. if self.state.mode == 'request_resource':
  121. # Go and request the required resource
  122. self.state.mode = 'wait_resource'
  123. self.state.timer = float('inf')
  124. elif self.state.mode == 'active':
  125. # Finished execution, so release resources
  126. self.state.mode = 'inactive'
  127. self.state.timer = 0.0
  128. self.state.timer = float('inf')
  129. self.state.counter += 1
  130. return self.state
  131. """
  132. extTransition = """
  133. self.state.timer -= self.elapsed
  134. if self.state.mode == 'inactive' and self.my_ports['control_in'] in inputs:
  135. # Got control token, so ask for the required resources
  136. self.state.mode = 'request_resource'
  137. self.state.timer = 0.0
  138. # NOTE this violates DEVS, though is easy to debug
  139. #print('Activate ' + str(self.state.name) + ' at time ' + str(self.time_last[0] + self.elapsed))
  140. elif self.state.mode == 'wait_resource' and self.my_ports['resource_in'] in inputs and inputs[self.my_ports['resource_in']]['id'] == '%s-%s' % (self.state.name, self.state.counter):
  141. # Got required resources, so start execution
  142. self.state.mode = 'active'
  143. self.state.timer = self.state.random_sample()
  144. return self.state
  145. """
  146. }
  147. InputPort act_ri {
  148. name = "resource_in"
  149. }
  150. OutputPort act_ro {
  151. name = "resource_out"
  152. }
  153. DEVSBlockToPort (Activity, act_ri) {}
  154. DEVSBlockToPort (Activity, act_ro) {}
  155. InputPort act_ci {
  156. name = "control_in"
  157. }
  158. OutputPort act_co {
  159. name = "control_out"
  160. }
  161. DEVSBlockToPort (Activity, act_ci) {}
  162. DEVSBlockToPort (Activity, act_co) {}
  163. AtomicDEVSBlock ParallelSplit {
  164. name = "ParallelSplit"
  165. initialState = """
  166. self.state, self.elapsed = False, 0.0
  167. """
  168. timeAdvance = """
  169. if self.state:
  170. return 0.0
  171. else:
  172. return float('inf')
  173. """
  174. outputFnc = """
  175. return {self.my_ports['control_out']: {}}
  176. """
  177. intTransition = """
  178. return False
  179. """
  180. extTransition = """
  181. return True
  182. """
  183. }
  184. InputPort split_ci {
  185. name = "control_in"
  186. }
  187. OutputPort split_co {
  188. name = "control_out"
  189. }
  190. DEVSBlockToPort (ParallelSplit, split_ci) {}
  191. DEVSBlockToPort (ParallelSplit, split_co) {}
  192. AtomicDEVSBlock Synchronization {
  193. name = "Synchronization"
  194. initialState = """
  195. self.state, self.elapsed = {'current': self.parameters[0], 'max': self.parameters[0]}, 0.0
  196. """
  197. timeAdvance = """
  198. if self.state['current'] == 0:
  199. return 0.0
  200. else:
  201. return float('inf')
  202. """
  203. outputFnc = """
  204. return {self.my_ports['control_out']: {}}
  205. """
  206. intTransition = """
  207. self.state['current'] = self.state['max']
  208. return self.state
  209. """
  210. extTransition = """
  211. self.state['current'] -= 1
  212. return self.state
  213. """
  214. }
  215. InputPort syn_ci {
  216. name = "control_in"
  217. }
  218. OutputPort syn_co {
  219. name = "control_out"
  220. }
  221. DEVSBlockToPort (Synchronization, syn_ci) {}
  222. DEVSBlockToPort (Synchronization, syn_co) {}
  223. AtomicDEVSBlock ExclusiveChoice {
  224. name = "ExclusiveChoice"
  225. initialState = """
  226. class ExclusiveChoiceState(object):
  227. def __init__(self, distribution):
  228. self.counter = 0
  229. self.choice = None
  230. self.distribution = distribution
  231. def __str__(self):
  232. return str(vars(self))
  233. def make_choice(self):
  234. return self.distribution(self.counter)
  235. self.state, self.elapsed = ExclusiveChoiceState(self.parameters[0]), 0.0
  236. """
  237. timeAdvance = """
  238. if self.state.choice is not None:
  239. return 0.0
  240. else:
  241. return float('inf')
  242. """
  243. outputFnc = """
  244. if self.state.choice == True:
  245. return {self.my_ports['control_out1']: {}}
  246. else:
  247. return {self.my_ports['control_out2']: {}}
  248. """
  249. intTransition = """
  250. self.state.choice = None
  251. self.state.counter += 1
  252. return self.state
  253. """
  254. extTransition = """
  255. # Got a control token, so have to make a choice
  256. self.state.choice = self.state.make_choice()
  257. return self.state
  258. """
  259. }
  260. InputPort xor_ci {
  261. name = "control_in"
  262. }
  263. OutputPort xor_co1 {
  264. name = "control_out1"
  265. }
  266. OutputPort xor_co2 {
  267. name = "control_out2"
  268. }
  269. DEVSBlockToPort (ExclusiveChoice, xor_ci) {}
  270. DEVSBlockToPort (ExclusiveChoice, xor_co1) {}
  271. DEVSBlockToPort (ExclusiveChoice, xor_co2) {}
  272. AtomicDEVSBlock SimpleMerge {
  273. name = "SimpleMerge"
  274. initialState = """
  275. self.state, self.elapsed = False, 0.0
  276. """
  277. timeAdvance = """
  278. if self.state:
  279. return 0.0
  280. else:
  281. return float('inf')
  282. """
  283. outputFnc = """
  284. return {self.my_ports['control_out']: {}}
  285. """
  286. intTransition = """
  287. return False
  288. """
  289. extTransition = """
  290. return True
  291. """
  292. }
  293. InputPort or_ci {
  294. name = "control_in"
  295. }
  296. OutputPort or_co {
  297. name = "control_out"
  298. }
  299. DEVSBlockToPort (SimpleMerge, or_ci) {}
  300. DEVSBlockToPort (SimpleMerge, or_co) {}
  301. AtomicDEVSBlock MultiInstance {
  302. name = "MultiInstance"
  303. initialState = """
  304. class MultiInstanceState(object):
  305. def __init__(self, name, num, distribution):
  306. self.spawned = num
  307. self.collected = 0
  308. self.counter = 0
  309. self.mode = 'inactive'
  310. self.running_tasks = []
  311. self.requested = []
  312. self.name = name
  313. self.distribution = distribution
  314. def __str__(self):
  315. return str(vars(self))
  316. def task_time(self):
  317. return self.distribution(self.counter)
  318. self.state, self.elapsed = MultiInstanceState(self.parameters[0], self.parameters[1], self.parameters[2]), 0.0
  319. """
  320. timeAdvance = """
  321. if self.state.mode == 'finish':
  322. return 0.0
  323. elif self.state.running_tasks:
  324. return self.state.running_tasks[0][0]
  325. elif self.state.mode == 'request_resources':
  326. return 0.0
  327. else:
  328. return float('inf')
  329. """
  330. outputFnc = """
  331. if self.state.mode == 'request_resources':
  332. # Request all resources in one go
  333. return {self.my_ports['resource_out']: [{'type': 'request', 'id': i} for i in self.state.requested]}
  334. elif self.state.mode == 'active':
  335. # Finished an instance, so release it
  336. return {self.my_ports['resource_out']: [{'type': 'release'}]}
  337. elif self.state.mode == 'finish':
  338. # Finished execution of all, so pass on token
  339. return {self.my_ports['control_out']: {}}
  340. else:
  341. return {}
  342. """
  343. intTransition = """
  344. ta = self.timeAdvance()
  345. for t in self.state.running_tasks:
  346. t[0] -= ta
  347. if self.state.mode == 'active':
  348. # Finished an instance, so pop it
  349. del self.state.running_tasks[0]
  350. self.state.collected += 1
  351. if self.state.collected == self.state.spawned:
  352. self.state.mode = 'finish'
  353. elif self.state.mode == 'request_resources':
  354. # Requested resources, so be ready for a response
  355. self.state.mode = 'active'
  356. elif self.state.mode == 'finish':
  357. self.state.mode = 'inactive'
  358. self.state.collected = 0
  359. self.state.counter += 1
  360. self.state.running_tasks = []
  361. return self.state
  362. """
  363. extTransition = """
  364. # Got input, so have to spawn #num of them
  365. for t in self.state.running_tasks:
  366. t[0] -= self.elapsed
  367. if self.state.mode == 'inactive' and self.my_ports['control_in'] in inputs:
  368. self.state.mode = 'request_resources'
  369. self.state.requested = ['%s-%s-%s' % (self.state.name, self.state.counter, i) for i in range(self.state.spawned)]
  370. if self.state.mode in ['active', 'release_resource'] and self.my_ports['resource_in'] in inputs:
  371. # Got a resource, so allocate it to an activity
  372. self.state.running_tasks.append([self.state.task_time(), self.state.requested.pop(0)])
  373. # NOTE this violates DEVS, though is easy to debug
  374. #print('Spawn ' + str(self.state.running_tasks[-1][1]) + ' at time ' + str(self.time_last[0] + self.elapsed))
  375. self.state.running_tasks.sort()
  376. return self.state
  377. """
  378. }
  379. InputPort mi_ci {
  380. name = "control_in"
  381. }
  382. OutputPort mi_co {
  383. name = "control_out"
  384. }
  385. InputPort mi_ri {
  386. name = "resource_in"
  387. }
  388. OutputPort mi_ro {
  389. name = "resource_out"
  390. }
  391. DEVSBlockToPort (MultiInstance, mi_ci) {}
  392. DEVSBlockToPort (MultiInstance, mi_co) {}
  393. DEVSBlockToPort (MultiInstance, mi_ri) {}
  394. DEVSBlockToPort (MultiInstance, mi_ro) {}