mini_modify.alc 18 KB

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