mini_modify.alc 21 KB

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