mini_modify.alc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. include "primitives.alh"
  2. include "constructors.alh"
  3. include "object_operations.alh"
  4. include "library.alh"
  5. include "conformance_scd.alh"
  6. include "io.alh"
  7. include "metamodels.alh"
  8. include "modelling.alh"
  9. Boolean verbose = True
  10. String function pretty_print(model : Element):
  11. Element keys_m
  12. String type
  13. String v_m
  14. Element attr_list
  15. Element attr_keys
  16. String attr_key
  17. String result
  18. result = ""
  19. keys_m = dict_keys(model["model"])
  20. while (read_nr_out(keys_m) > 0):
  21. v_m = set_pop(keys_m)
  22. type = read_type(model["metamodel"], read_type(model, v_m))
  23. if (bool_or(type == "Class", type == "Association")):
  24. result = result + (((" " + v_m) + " : ") + read_type(model, v_m))
  25. result = result + "\n"
  26. if (type == "Association"):
  27. result = result + (((" " + reverseKeyLookup(model["model"], read_edge_src(model["model"][v_m]))) + " --> ") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][v_m])))
  28. result = result + "\n"
  29. // Defines attributes
  30. attr_list = getInstantiatableAttributes(model, v_m)
  31. attr_keys = dict_keys(attr_list)
  32. while (0 < read_nr_out(attr_keys)):
  33. attr_key = set_pop(attr_keys)
  34. result = result + ((((" " + attr_key) + " : ") + cast_v2s(attr_list[attr_key])))
  35. result = result + "\n"
  36. // Has attributes
  37. attr_list = getAttributeList(model, v_m)
  38. attr_keys = dict_keys(attr_list)
  39. while (0 < read_nr_out(attr_keys)):
  40. attr_key = set_pop(attr_keys)
  41. if (element_eq(read_attribute(model, v_m, attr_key), read_root())):
  42. result = result + ((((" " + cast_v2s(attr_key)) + " : ") + cast_v2s(attr_list[attr_key])) + " = (undefined)")
  43. else:
  44. result = result + (((((" " + cast_v2s(attr_key)) + " : ") + cast_v2s(attr_list[attr_key])) + " = ") + cast_v2s(read_attribute(model, v_m, attr_key)))
  45. result = result + "\n"
  46. return result!
  47. String function cmd_help_m(write : Boolean):
  48. String result
  49. result = ""
  50. result = result + "Allowed operations:\n"
  51. if (write):
  52. result = result + " == READ/WRITE ==\n"
  53. result = result + " instantiate_node -- Create a new model element (node)\n"
  54. result = result + " instantiate_edge -- Create a new model element (edge)\n"
  55. result = result + " delete -- Delete an existing element\n"
  56. result = result + " attr_add -- Add an attribute to an element\n"
  57. result = result + " attr_add_code -- Add a coded attribute to an element\n"
  58. result = result + " attr_del -- Delete an attribute of an element\n"
  59. result = result + " attr_modify -- Modify an attribute of an element\n"
  60. result = result + " retype -- Change the type of an element\n"
  61. result = result + " upload -- Upload a completely new model\n"
  62. else:
  63. result = result + " == READ-ONLY ==\n"
  64. result = result + " read_outgoing -- Prints the list of outgoing links of an element\n"
  65. result = result + " read_incoming -- Prints the list of incoming links to an element\n"
  66. result = result + " list -- Prints the list of elements in the model\n"
  67. result = result + " list_full -- Prints the list of all elements in the model\n"
  68. result = result + " types -- Prints the list of elements that can be instantiated\n"
  69. result = result + " read -- Prints the current state of a model element\n"
  70. result = result + " verify -- Check whether the model conforms to the metamodel\n"
  71. result = result + " exit -- Leave the modification interface\n"
  72. return result!
  73. String function cmd_upload(write : Boolean, model : Element):
  74. Element new_model
  75. if (write):
  76. output("Waiting for model constructors...")
  77. new_model = construct_model_raw(model["metamodel"])
  78. dict_overwrite(model, "model", new_model["model"])
  79. dict_overwrite(model, "type_mapping", new_model["type_mapping"])
  80. return "Success"!
  81. else:
  82. return "Permission denied to write"!
  83. String function cmd_instantiate_node(write : Boolean, model : Element, mm_type_name : String, element_name : String):
  84. if (write):
  85. if (dict_in(model["metamodel"]["model"], mm_type_name)):
  86. if (dict_in(model["model"], element_name)):
  87. return "Element exists: " + element_name!
  88. else:
  89. if (is_edge(model["metamodel"]["model"][mm_type_name])):
  90. return "Element is not a node but an edge: " + mm_type_name!
  91. element_name = instantiate_node(model, mm_type_name, element_name)
  92. return "Success: " + element_name!
  93. else:
  94. return "Element not found: " + mm_type_name!
  95. else:
  96. return "Permission denied to write"!
  97. String function cmd_instantiate_edge(write : Boolean, model : Element, mm_type_name : String, element_name : String, source_name : String, target_name : String):
  98. if (write):
  99. if (dict_in(model["metamodel"]["model"], mm_type_name)):
  100. if (dict_in(model["model"], element_name)):
  101. return "Element exists: " + element_name!
  102. else:
  103. if (is_edge(model["metamodel"]["model"][mm_type_name])):
  104. if (dict_in(model["model"], source_name)):
  105. if (dict_in(model["model"], target_name)):
  106. element_name = instantiate_link(model, mm_type_name, element_name, source_name, target_name)
  107. return "Success: " + element_name!
  108. else:
  109. return "Element not found: " + target_name!
  110. else:
  111. return "Element not found: " + source_name!
  112. else:
  113. return "Element is a node not an edge: " + mm_type_name!
  114. else:
  115. return "Element not found: " + mm_type_name!
  116. else:
  117. return "Permission denied to write"!
  118. String function cmd_attr_add(write : Boolean, model : Element, element_name : String, attr_name : String, value : Element):
  119. if (write):
  120. if (dict_in(model["model"], element_name)):
  121. Element attrs
  122. attrs = getAttributeList(model, element_name)
  123. if (set_in(dict_keys(attrs), attr_name)):
  124. instantiate_attribute(model, element_name, attr_name, value)
  125. return "Success"!
  126. else:
  127. return "Attribute not found: " + attr_name!
  128. else:
  129. return "Element not found: " + element_name!
  130. else:
  131. return "Permission denied to write"!
  132. String function cmd_attr_add_code(write : Boolean, model : Element, element_name : String, attr_name : String):
  133. if (write):
  134. if (dict_in(model["model"], element_name)):
  135. Element attrs
  136. attrs = getAttributeList(model, element_name)
  137. if (set_in(dict_keys(attrs), attr_name)):
  138. output("Waiting for code constructors...")
  139. instantiate_attribute_code(model, element_name, attr_name, construct_function())
  140. return "Success"!
  141. else:
  142. return "Attribute not found: " + attr_name!
  143. else:
  144. return "Element not found: " + element_name!
  145. else:
  146. return "Permission denied to write"!
  147. String function cmd_attr_del(write : Boolean, model : Element, element_name : String, attr_name : String):
  148. if (write):
  149. if (dict_in(model["model"], element_name)):
  150. Element attrs
  151. attrs = getAttributeList(model, element_name)
  152. if (set_in(dict_keys(attrs), attr_name)):
  153. unset_attribute(model, element_name, attr_name)
  154. return "Success"!
  155. else:
  156. return "Attribute not found: " + attr_name!
  157. else:
  158. return "Element not found: " + element_name!
  159. else:
  160. return "Permission denied to write"!
  161. String function cmd_delete(write : Boolean, model : Element, element_name : String):
  162. if (write):
  163. if (dict_in(model["model"], element_name)):
  164. model_delete_element(model, element_name)
  165. return "Success"!
  166. else:
  167. return "Element not found: " + element_name!
  168. else:
  169. return "Permission denied to write"!
  170. String function cmd_list(model : Element):
  171. Element keys_m
  172. String v_m
  173. String result
  174. String typename
  175. result = "Success: "
  176. keys_m = dict_keys(model["model"])
  177. while (read_nr_out(keys_m) > 0):
  178. v_m = set_pop(keys_m)
  179. // Filter out anonymous objects
  180. if (bool_not(string_startswith(v_m, "__"))):
  181. typename = read_type(model, v_m)
  182. result = (result + (((" " + v_m) + " : ") + typename)) + "\n"
  183. return result!
  184. String function cmd_list_full(model : Element):
  185. Element keys_m
  186. String v_m
  187. String result
  188. String typename
  189. result = "Success: "
  190. keys_m = dict_keys(model["model"])
  191. while (read_nr_out(keys_m) > 0):
  192. v_m = set_pop(keys_m)
  193. // Filter out anonymous objects
  194. typename = read_type(model, v_m)
  195. result = (result + (((" " + v_m) + " : ") + typename)) + "\n"
  196. return result!
  197. String function cmd_read_outgoing(model : Element, element_name : String, type : String):
  198. String result
  199. Element elems
  200. if (dict_in(model["model"], element_name)):
  201. result = "Success: "
  202. elems = allOutgoingAssociationInstances(model, element_name, type)
  203. while (read_nr_out(elems) > 0):
  204. result = string_join(result, set_pop(elems)) + "\n"
  205. return result!
  206. else:
  207. return "Element not found: " + element_name!
  208. String function cmd_read_incoming(model : Element, element_name : String, type : String):
  209. String result
  210. Element elems
  211. if (dict_in(model["model"], element_name)):
  212. result = "Success: "
  213. elems = allIncomingAssociationInstances(model, element_name, type)
  214. while (read_nr_out(elems) > 0):
  215. result = string_join(result, set_pop(elems)) + "\n"
  216. return result!
  217. else:
  218. return "Element not found: " + element_name!
  219. String function cmd_connections_between(model : Element, source_name : String, target_name : String):
  220. String result
  221. Element options
  222. if (dict_in(model["model"], source_name)):
  223. if (dict_in(model["model"], target_name)):
  224. result = "Success: "
  225. options = allowedAssociationsBetween(model, source_name, target_name)
  226. while (read_nr_out(options) > 0):
  227. result = string_join(result, set_pop(options)) + "\n"
  228. else:
  229. return ("Element not found: " + target_name)!
  230. else:
  231. return ("Element not found: " + source_name)!
  232. String function cmd_read(model : Element, element_name : String):
  233. String result
  234. Element attr_list
  235. Element attr_keys
  236. String attr_key
  237. result = "Success: "
  238. if (dict_in(model["model"], element_name)):
  239. result = ((result + "ID: ") + element_name) + "\n"
  240. result = ((result + "Type: ") + read_type(model, element_name)) + "\n"
  241. if (is_edge(model["model"][element_name])):
  242. result = ((result + "Source: ") + reverseKeyLookup(model["model"], read_edge_src(model["model"][element_name]))) + "\n"
  243. result = ((result + "Destination: ") + reverseKeyLookup(model["model"], read_edge_dst(model["model"][element_name]))) + "\n"
  244. if (has_value(model["model"][element_name])):
  245. result = ((result + "Value: ") + cast_v2s(model["model"][element_name])) + "\n"
  246. result = result + "Defines attributes:\n"
  247. attr_list = getInstantiatableAttributes(model, element_name)
  248. attr_keys = dict_keys(attr_list)
  249. while (0 < read_nr_out(attr_keys)):
  250. attr_key = set_pop(attr_keys)
  251. result = ((((result + " ") + attr_key) + " : ") + cast_v2s(attr_list[attr_key])) + "\n"
  252. result = result + "Attributes:\n"
  253. attr_list = getAttributeList(model, element_name)
  254. attr_keys = dict_keys(attr_list)
  255. while (0 < read_nr_out(attr_keys)):
  256. attr_key = set_pop(attr_keys)
  257. result = ((((((result + " ") + cast_v2s(attr_key)) + " : ") + cast_v2s(attr_list[attr_key])) + " = ") + cast_v2s(read_attribute(model, element_name, attr_key))) + "\n"
  258. return result!
  259. else:
  260. return "Element not found: " + element_name!
  261. String function cmd_types(model : Element):
  262. Element keys_t
  263. String v_t
  264. String result
  265. keys_t = dict_keys(model["metamodel"]["model"])
  266. result = "Success: "
  267. while (read_nr_out(keys_t) > 0):
  268. v_t = set_pop(keys_t)
  269. if (bool_not(string_startswith(v_t, "__"))):
  270. result = (result + string_join((" " + v_t) + " : ", read_type(model["metamodel"], v_t))) + "\n"
  271. return result!
  272. String function cmd_retype(write : Boolean, model : Element, element_name : String, new_type : String):
  273. if (write):
  274. if (dict_in(model["model"], element_name)):
  275. if (dict_in(model["metamodel"]["model"], new_type)):
  276. retype(model, element_name, new_type)
  277. return "Success"!
  278. else:
  279. return "Element not found: " + new_type!
  280. else:
  281. return "Element not found: " + element_name!
  282. else:
  283. return "Permission denied to write"!
  284. String function cmd_read_association_source(write : Boolean, model : Element, element_name : String):
  285. if (dict_in(model["model"], element_name)):
  286. if (is_edge(model["model"][element_name])):
  287. return "Success: " + readAssociationSource(model, element_name)!
  288. else:
  289. return "Not an association: " + element_name!
  290. else:
  291. return "Element not found: " + element_name!
  292. String function cmd_read_association_destination(write : Boolean, model : Element, element_name : String):
  293. if (dict_in(model["model"], element_name)):
  294. if (is_edge(model["model"][element_name])):
  295. return "Success: " + readAssociationDestination(model, element_name)!
  296. else:
  297. return "Not an association: " + element_name!
  298. else:
  299. return "Element not found: " + element_name!
  300. Element function modify(model : Element, write : Boolean):
  301. String cmd
  302. output("Model loaded, ready for commands!")
  303. while (True):
  304. cmd = input()
  305. if (cmd == "help"):
  306. output(cmd_help_m(write))
  307. elif (cmd == "exit"):
  308. return model!
  309. elif (cmd == "upload"):
  310. output(cmd_upload(write, model))
  311. elif (cmd == "instantiate_node"):
  312. output(cmd_instantiate_node(write, model, single_input("Type?"), single_input("Name?")))
  313. elif (cmd == "instantiate_edge"):
  314. output(cmd_instantiate_edge(write, model, single_input("Type?"), single_input("Name?"), single_input("Source?"), single_input("Target?")))
  315. elif (cmd == "attr_add"):
  316. output(cmd_attr_add(write, model, single_input("Name?"), single_input("Attribute name?"), single_input("Value?")))
  317. elif (cmd == "attr_add_code"):
  318. output(cmd_attr_add_code(write, model, single_input("Name?"), single_input("Attribute name?")))
  319. elif (cmd == "attr_del"):
  320. output(cmd_attr_del(write, model, single_input("Name?"), single_input("Attribute_name?")))
  321. elif (cmd == "delete"):
  322. output(cmd_delete(write, model, single_input("Name?")))
  323. elif (cmd == "nice_list"):
  324. output(pretty_print(model))
  325. elif (cmd == "list"):
  326. output(cmd_list(model))
  327. elif (cmd == "list_full"):
  328. output(cmd_list_full(model))
  329. elif (cmd == "read_outgoing"):
  330. output(cmd_read_outgoing(model, single_input("Name?"), single_input("Type?")))
  331. elif (cmd == "read_incoming"):
  332. output(cmd_read_incoming(model, single_input("Name?"), single_input("Type?")))
  333. elif (cmd == "read"):
  334. output(cmd_read(model, single_input("Name?")))
  335. elif (cmd == "verify"):
  336. output("Success: " + conformance_scd(model))
  337. elif (cmd == "types"):
  338. output(cmd_types(model))
  339. elif (cmd == "retype"):
  340. output(cmd_retype(write, model, single_input("Name?"), single_input("New type?")))
  341. elif (cmd == "read_association_source"):
  342. output(cmd_read_association_source(write, model, single_input("Name?")))
  343. elif (cmd == "read_association_destination"):
  344. output(cmd_read_association_destination(write, model, single_input("Name?")))
  345. elif (cmd == "connections_between"):
  346. output(cmd_connections_between(model, single_input("Source element?"), single_input("Target element?")))
  347. else:
  348. output("Unknown command while modelling: " + cast_v2s(cmd))
  349. output("Use command 'help' to get a list of available commands")
  350. return model!
  351. String function single_input(prompt : String):
  352. if (verbose):
  353. output(prompt)
  354. return input()!
  355. Element function set_input(prompt : String):
  356. Element result
  357. Element inp
  358. if (verbose):
  359. output(prompt)
  360. output("-- Set input: empty string to terminate set")
  361. result = set_create()
  362. while (True):
  363. inp = input()
  364. if (value_eq(inp, "")):
  365. return result!
  366. else:
  367. set_add(result, inp)
  368. Element function dict_input(prompt : String):
  369. Element result
  370. Element key
  371. if (verbose):
  372. output(prompt)
  373. output("-- Dict input: empty key to terminate dict")
  374. result = set_create()
  375. while (True):
  376. key = input()
  377. if (value_eq(key, "")):
  378. return result!
  379. else:
  380. dict_add(result, key, input())
  381. Void function set_verbose(v : Boolean):
  382. verbose = v
  383. return!