mini_modify.alc 22 KB

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