mini_modify.alc 22 KB

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