1 % (c) 2018-2026 Lehrstuhl fuer Softwaretechnik und Programmiersprachen,
2 % Heinrich Heine Universitaet Duesseldorf
3 % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html)
4
5
6 :- module(tools_matching,
7 [fuzzy_match_codes_lower_case/2,
8 fuzzy_match_codes/2,
9 codes_to_lower_case/2, % to lower case, also performs Unicode simplifications
10 decompose_codes_id/2, % optionally remove leading machine prefixes upon backtracking
11 get_current_keywords/1, get_current_expr_keywords/1,
12 is_b_keyword/2, is_rules_dsl_keyword/2,
13 get_all_svg_classes/1, is_svg_shape_class/1,
14 get_all_svg_attributes/1, is_svg_number_attribute/2, is_svg_color_attribute/1,
15 is_svg_attribute/1,
16 is_svg_attribute_with_fixed_text_values/3, check_svg_attribute_text_alternative/2,
17 fix_svg_attribute_based_on_value/3, svg_attribute_default_value/2,
18 is_virtual_svg_attribute/1,
19 is_svg_color_name/1, check_is_svg_color_name/1,
20 is_svg_template/2,
21 is_html_tag/1, is_html_attribute/1,
22 get_all_dot_attributes/1, is_dot_attribute/1,
23 is_dot_color_name/1,
24 fix_svg_attribute/2, dotshape2svg_class/2,
25 get_possible_preferences/1, get_possible_preferences_matches_msg/2,
26 get_possible_top_level_event_matches_msg/2,
27 get_possible_operation_matches_msg/2,
28 get_possible_fuzzy_matches_msg/3,
29 get_possible_completions_msg/3,
30 get_possible_fuzzy_matches_and_completions_msg/3, % both in one
31 get_possible_fuzzy_matches_completions_and_inner_msg/3 % also looking for inner matches
32 ]).
33
34 :- use_module(error_manager).
35 :- use_module(self_check).
36 :- use_module(library(lists)).
37
38 :- use_module(module_information).
39
40 :- module_info(group,infrastructure).
41 :- module_info(description,'A few utilities for fuzzy matching and completion.').
42
43 :- set_prolog_flag(double_quotes, codes).
44
45 :- use_module(tools,[arg_is_number/2,ajoin/2,ajoin_with_sep/3]).
46
47 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("a","A")).
48 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("aBcD","ABCd")).
49 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("aBcD","ABxCd")).
50 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("aBxcD","ABCd")).
51 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("aBcD","ABCdx")).
52 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("aBcDx","ABCd")).
53 :- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("a_Bc_D","AB__Cd")).
54 %:- assert_must_succeed(tools_matching:fuzzy_match_codes_lower_case("äÄ","aA")).
55 :- assert_must_fail(tools_matching:fuzzy_match_codes_lower_case("abc","cba")).
56
57
58 fuzzy_match_codes_lower_case(Codes1,Codes2) :-
59 codes_to_lower_case(Codes1,LCodes1),
60 codes_to_lower_case(Codes2,LCodes2),
61 fuzzy_match_codes(LCodes1,LCodes2).
62
63 :- assert_must_succeed(tools_matching:fuzzy_match_codes("aBcD","aBcD")).
64 :- assert_must_succeed(tools_matching:fuzzy_match_codes("aBxcD","aBcD")).
65 :- assert_must_succeed(tools_matching:fuzzy_match_codes("aBcD","aBcxD")).
66 :- assert_must_succeed(tools_matching:fuzzy_match_codes("aBcD","aBcDx")).
67 :- assert_must_succeed(tools_matching:fuzzy_match_codes("xaBcD","aBcD")).
68 :- assert_must_succeed(tools_matching:fuzzy_match_codes("aBcD","xaBcD")).
69 :- assert_must_succeed(tools_matching:fuzzy_match_codes("version","verison")).
70 :- assert_must_fail(tools_matching:fuzzy_match_codes("abc","ABC")).
71
72 fuzzy_match_codes([],[]).
73 ?fuzzy_match_codes([H|T1],[H|T2]) :- !,fuzzy_match_codes(T1,T2).
74 fuzzy_match_codes([_|T],[_|T]) :- !. % one character rewritten
75 fuzzy_match_codes([H1|T1],L2) :- possible_skip_char(H1),!, % underscore _
76 ? fuzzy_match_codes(T1,L2).
77 fuzzy_match_codes(L1,[H2|T2]) :- possible_skip_char(H2),!,
78 fuzzy_match_codes(L1,T2).
79 fuzzy_match_codes([_|T],T) :- !. % one character too much
80 fuzzy_match_codes(T,[_|T]) :- !. % one character too few
81 fuzzy_match_codes([H1,H2|T],[H2,H1|T]) :- !. % swapping of two characters
82
83
84 %:- assert_must_succeed(tools_matching:codes_to_lower_case("äÄöAa","aaoaa")).
85
86 codes_to_lower_case([],[]).
87 codes_to_lower_case([C|T],[LC|LT]) :- code_to_lower_case(C,LC), codes_to_lower_case(T,LT).
88
89 % TO DO: normalise more UNICODE symbols, ...
90
91 code_to_lower_case(Char,LC_Char) :- Char >= 65, Char =< 90,!, LC_Char is Char+32.
92 code_to_lower_case(Char,LC_Char) :- Char >= 8320, Char =< 8329,!, LC_Char is Char-8272. % Unicode Subscripts
93 code_to_lower_case(8242,R) :- !, R=8242. % Unicode Prime
94 code_to_lower_case(8216,R) :- !, R=8242.
95 code_to_lower_case(8217,R) :- !, R=8242.
96 code_to_lower_case(Char,R) :- Char >= 192, Char =< 197,!, R=97. % upper-case a
97 code_to_lower_case(Char,R) :- Char >= 224, Char =< 229,!, R=97. % lower-case a
98 code_to_lower_case(Char,R) :- Char >= 200, Char =< 203,!, R=101. % upper-case e
99 code_to_lower_case(Char,R) :- Char >= 232, Char =< 235,!, R=101. % lower-case e
100 code_to_lower_case(Char,R) :- Char >= 204, Char =< 207,!, R=105. % upper-case i
101 code_to_lower_case(Char,R) :- Char >= 236, Char =< 239,!, R=105. % lower-case i
102 code_to_lower_case(Char,R) :- Char >= 210, Char =< 214,!, R=111. % upper-case o
103 code_to_lower_case(Char,R) :- Char >= 242, Char =< 246,!, R=111. % lower-case o
104 code_to_lower_case(Char,R) :- Char >= 217, Char =< 220,!, R=117. % upper-case u
105 code_to_lower_case(Char,R) :- Char >= 249, Char =< 252,!, R=117. % lower-case u
106 code_to_lower_case(253,R) :- !, R=121. % ý -> y
107 code_to_lower_case(209,R) :- !, R=110. % Ñ -> n
108 code_to_lower_case(241,R) :- !, R=110. % ñ -> n
109 code_to_lower_case(231,R) :- !, R=99. % ç -> c
110 code_to_lower_case(223,R) :- !, R=115. % ß -> s
111 code_to_lower_case(C,C).
112
113 % use_module(library(between)), between(150,255,R), atom_codes(A,[R]), format("~w : ~w~n",[R,A]),fail.
114
115 possible_skip_char(95). % _
116
117 :- use_module(specfile,[b_or_z_mode/0, csp_mode/0, xtl_mode/0, animation_minor_mode/1, classical_b_mode/0]).
118
119 get_current_expr_keywords(List) :-
120 get_current_keywords([expr,external_funs,pragma,predicate],List).
121 get_current_keywords(List) :-
122 get_current_keywords([expr,external_funs,pragma,predicate,prob_definitions,section,subst],List).
123
124 get_current_keywords(Types,List) :- b_or_z_mode,!,
125 (animation_minor_mode(Minor)
126 -> (classical_b_mode
127 % e.g., for rules_dsl allow both B and rules_dsl keywords at the moment, TODO: remove sections
128 % TODO: we should also ensure this is active for VisB expressions or when the REPL is classical B mode
129 -> get_keywords(Minor,Types,List1),
130 get_keywords(b,Types,List2),
131 append(List1,List2,List)
132 ; get_keywords(Minor,Types,List))
133 ; get_keywords(b,Types,List)).
134 get_current_keywords(_,List) :- csp_mode,!,
135 findall(Def,csp_keyword(Def),List).
136 get_current_keywords(_,List) :- xtl_mode,!,
137 findall(Def,xtl_keyword(Def),List).
138 get_current_keywords(_,[]).
139
140 % -----------------
141
142 csp_keyword(and).
143 csp_keyword(card).
144 csp_keyword(channel).
145 csp_keyword(datatype).
146 csp_keyword(diff).
147 csp_keyword(elem).
148 csp_keyword(empty).
149 csp_keyword(false).
150 csp_keyword(head).
151 csp_keyword(inter).
152 csp_keyword(length).
153 csp_keyword(let).
154 csp_keyword(member).
155 csp_keyword(mod).
156 csp_keyword(nametype).
157 csp_keyword(not).
158 csp_keyword(null).
159 csp_keyword(or).
160 csp_keyword(set).
161 csp_keyword(subtype).
162 csp_keyword(tail).
163 csp_keyword(true).
164 csp_keyword(union).
165 csp_keyword(within).
166 csp_keyword('CHAOS').
167 csp_keyword('Inter').
168 csp_keyword('Seq').
169 csp_keyword('Set').
170 csp_keyword('SKIP').
171 csp_keyword('STOP').
172 csp_keyword('Union').
173
174
175 xtl_keyword(prop).
176 xtl_keyword(start).
177 xtl_keyword(symb_trans).
178 xtl_keyword(symb_trans_enabled).
179 xtl_keyword(trans).
180 xtl_keyword(trans_prop).
181 xtl_keyword(animation_image).
182 xtl_keyword(animation_image_click_transition).
183 xtl_keyword(animation_image_right_click_transition).
184 xtl_keyword(animation_function_result).
185 xtl_keyword(heuristic_function_active).
186 xtl_keyword(heuristic_function_result).
187 xtl_keyword(prob_game_info).
188 xtl_keyword(prob_pragma_string).
189 xtl_keyword(nr_state_properties).
190
191 % -----------------
192
193 get_keywords(Mode,Types,List) :-
194 (Mode=b,select(prob_definitions,Types,Types1)
195 -> findall(Def,prob_special_def(Def),Ids1)
196 ; Ids1=[], Types1=Types
197 ),
198 ? (Mode=b,select(external_funs,Types1,Types2)
199 -> findall(Def,prob_external_fun(Def),Ids2,Ids1)
200 ; Ids2=Ids1, Types2=Types1
201 ),
202 findall(ID,(keyword(ID,Type,Modes), member(Mode,Modes), member(Type,Types2)),Ids,Ids2),
203 sort(Ids,List).
204
205 :- use_module(external_function_declarations,[external_function_library/2]).
206 ?prob_external_fun(Fun) :- external_function_library(Fun,File),
207 member(File,['LibraryStrings.def']). % ideally we want to only show the included libraries
208
209 prob_special_def(Def) :- special_definitions(Def,_).
210 prob_special_def(Def) :- set_pref_keyword(Def,_).
211 prob_special_def(Def) :- operation_pref_keyword(Def).
212
213 special_definitions('ASSERT_CTL',model_check).
214 special_definitions('ASSERT_LTL',model_check).
215 special_definitions('GOAL',model_check).
216 special_definitions('HEURISTIC_FUNCTION',model_check).
217 special_definitions('SCOPE',model_check).
218 special_definitions('CUSTOM_GRAPH',dot).
219 special_definitions('CUSTOM_GRAPH_EDGES',dot).
220 special_definitions('CUSTOM_GRAPH_NODES',dot).
221 special_definitions('VISB_DEFINITIONS_FILE',visb).
222 special_definitions('VISB_JSON_FILE',visb).
223 special_definitions('VISB_SVG_BOX',visb).
224 special_definitions('VISB_SVG_CONTENTS',visb).
225 special_definitions('VISB_SVG_EVENTS',visb).
226 special_definitions('VISB_SVG_FILE',visb).
227 special_definitions('VISB_SVG_HOVERS',visb).
228 special_definitions('VISB_SVG_OBJECTS',visb).
229 special_definitions('VISB_SVG_UPDATES',visb).
230 % this is a local identifier available inside event predicates: VISB_CLICK_META_INFOS
231 special_definitions('ANIMATION_CLICK',tkanim).
232 special_definitions('ANIMATION_EXPRESSION',tkanim).
233 special_definitions('ANIMATION_FUNCTION',tkanim).
234 special_definitions('ANIMATION_FUNCTION_DEFAULT',tkanim).
235 special_definitions('ANIMATION_IMG',tkanim).
236 special_definitions('ANIMATION_RIGHT_CLICK',tkanim).
237 special_definitions('ANIMATION_STR',tkanim).
238 special_definitions('ANIMATION_STR_JUSTIFY_LEFT',tkanim).
239 special_definitions('ANIMATION_STR_JUSTIFY_RIGHT',tkanim).
240 special_definitions('GAME_MCTS_RUNS',mcts).
241 special_definitions('GAME_MCTS_TIMEOUT',mcts).
242 special_definitions('GAME_MCTS_CACHE_LAST_TREE',mcts).
243 special_definitions('GAME_OVER',mcts).
244 special_definitions('GAME_PLAYER',mcts).
245 special_definitions('GAME_VALUE',mcts).
246 special_definitions('PROB_REQUIRED_VERSION',general).
247 special_definitions('SIMB_JSON_FILE',simb).
248 % TODO: scope_, FORCE_SYMMETRY_, for sets
249
250 :- use_module(bmachine,[b_top_level_operation/1]).
251 operation_pref_keyword(OpPrefAtom) :-
252 b_top_level_operation(Top),
253 op_prefix(Prefix),
254 atom_concat(Prefix,Top,OpPrefAtom).
255 op_prefix('MAX_OPERATIONS_').
256 op_prefix('OPERATION_REUSE_OFF_').
257 op_prefix('SEQUENCE_CHART_').
258 op_prefix('DESCRIPTION_FOR_').
259
260 set_pref_keyword(SetPrefAtom,Pref) :-
261 get_possible_preferences(Prefs),
262 member(Pref,Prefs),
263 atom_concat('SET_PREF_',Pref,SetPrefAtom).
264
265 ?is_b_keyword(ID,Type) :- keyword(ID,Type,L), member(b,L).
266 is_rules_dsl_keyword(ID,Type) :- keyword(ID,Type,L), member(rules_dsl,L).
267
268 % list of language specific and context specific keywords
269 keyword(not,predicate,[b,eventb]).
270 keyword(or,predicate,[b,eventb]).
271 keyword('true',expr,[eventb]). % truth in Rodin parser
272 keyword('false',expr,[eventb]). % falsity in Rodin parser
273 keyword('TRUE',expr,[b,eventb,tla]).
274 keyword('FALSE',expr,[b,eventb,tla]).
275 keyword('BOOL',expr,[b,eventb]).
276 keyword('bool',expr,[b,eventb]).
277 keyword('POW',expr,[b,eventb]).
278 keyword('POW1',expr,[b,eventb]).
279 keyword('FIN',expr,[b]). % not available in Event-B
280 keyword('FIN1',expr,[b]). % ditto
281 keyword('union',expr,[b,eventb]).
282 keyword('inter',expr,[b,eventb]).
283 keyword('UNION',expr,[b,eventb]).
284 keyword('INTER',expr,[b,eventb]).
285 keyword('INTEGER',expr,[b]).
286 keyword('NATURAL',expr,[b]).
287 keyword('NATURAL1',expr,[b]).
288 keyword('INT',expr,[b,eventb]).
289 keyword('NAT',expr,[b,eventb]).
290 keyword('NAT1',expr,[b,eventb]).
291 keyword('MININT',expr,[b]).
292 keyword('MAXINT',expr,[b]).
293 keyword('min',expr,[b,eventb]).
294 keyword('max',expr,[b,eventb]).
295 keyword('SIGMA',expr,[b]).
296 keyword('PI',expr,[b]).
297 keyword('STRING',expr,[b,tla]).
298 keyword('card',expr,[b,eventb]).
299 keyword('finite',expr,[eventb]).
300 keyword('@finite',expr,[b]).
301 keyword('dom',expr,[b,eventb]).
302 keyword('ran',expr,[b,eventb]).
303 keyword('id',expr,[b,eventb]).
304 keyword('@partition',expr,[b]).
305 keyword('partition',expr,[eventb]).
306 keyword('prj1',expr,[b,eventb]).
307 keyword('prj2',expr,[b,eventb]).
308 keyword('@prj1',expr,[b]).
309 keyword('@prj2',expr,[b]).
310 keyword('pred',expr,[b,eventb]).
311 keyword('succ',expr,[b,eventb]).
312 keyword('closure',expr,[b]).
313 keyword('closure1',expr,[b]).
314 keyword('iterate',expr,[b]).
315 keyword('fnc',expr,[b]). % also Event-B ?
316 keyword('rel',expr,[b]).
317
318 keyword('seq',expr,[b]).
319 keyword('seq1',expr,[b]).
320 keyword('iseq',expr,[b]).
321 keyword('iseq1',expr,[b]).
322 keyword('perm',expr,[b]).
323 keyword('size',expr,[b]).
324 keyword('rev',expr,[b]).
325 keyword('first',expr,[b]).
326 keyword('last',expr,[b]).
327 keyword('front',expr,[b]).
328 keyword('tail',expr,[b]).
329 keyword('conc',expr,[b]).
330 keyword('struct',expr,[b]).
331 keyword('rec',expr,[b]).
332 keyword('STRING',expr,[b]).
333
334 % TREE keywords
335 keyword('arity',expr,[b]).
336 keyword('bin',expr,[b]).
337 keyword('btree',expr,[b]).
338 keyword('const',expr,[b]).
339 keyword('father',expr,[b]).
340 keyword('infix',expr,[b]).
341 keyword('left',expr,[b]).
342 keyword('mirror',expr,[b]).
343 keyword('prefix',expr,[b]).
344 keyword('postfix',expr,[b]).
345 keyword('rank',expr,[b]).
346 keyword('right',expr,[b]).
347 keyword('sizet',expr,[b]).
348 keyword('son',expr,[b]).
349 keyword('sons',expr,[b]).
350 keyword('subtree',expr,[b]).
351 keyword('top',expr,[b]).
352 keyword('tree',expr,[b]).
353
354
355 % REAL keywords
356 keyword('floor',expr,[b]).
357 keyword('ceiling',expr,[b]).
358 keyword('real',expr,[b]).
359 keyword('REAL',expr,[b]).
360 keyword('FLOAT',expr,[b]).
361
362 % ---
363
364 keyword('btrue',predicate,[b]).
365 keyword('bfalse',predicate,[b]).
366
367 keyword('skip',subst,[b]).
368 keyword('ANY',subst,[b]).
369 keyword('ASSERT',subst,[b]).
370 keyword('BEGIN',subst,[b]).
371 keyword('CASE',subst,[b,tla]).
372 keyword('CHOICE',subst,[b]).
373 keyword('DO',subst,[b]).
374 keyword('EITHER',subst,[b]).
375 keyword('OR',subst,[b]).
376 keyword('OF',subst,[b]).
377 keyword('PRE',subst,[b]).
378 keyword('SELECT',subst,[b]).
379 keyword('WHERE',subst,[b]).
380 keyword('WHILE',subst,[b]).
381 keyword('WITH',subst,[b,tla]).
382
383 % --
384
385 keyword('ABSTRACT_CONSTANTS',section,[b]).
386 keyword('ABSTRACT_VARIABLES',section,[b]).
387 keyword('ASSERTIONS',section,[b]).
388 keyword('CONCRETE_CONSTANTS',section,[b]).
389 keyword('CONCRETE_VARIABLES',section,[b]).
390 keyword('CONSTANTS',section,[b,tla]).
391 keyword('CONSTRAINTS',section,[b]).
392 keyword('DEFINITIONS',section,[b]).
393 keyword('EVENT',section,[b]).
394 keyword('EXTENDS',section,[b,tla]).
395 keyword('FREETYPES',section,[b]).
396 keyword('IMPLEMENTATION',section,[b]).
397 keyword('IMPORTS',section,[b]).
398 keyword('INCLUDES',section,[b]).
399 keyword('INITIALISATION',section,[b]).
400 keyword('INITIALIZATION',section,[b]).
401 keyword('INVARIANT',section,[b]).
402 keyword('LOCAL_OPERATIONS',section,[b]).
403 keyword('MACHINE',section,[b]).
404 keyword('MODEL',section,[b]).
405 keyword('OPERATIONS',section,[b]).
406 keyword('PROMOTES',section,[b]).
407 keyword('PROPERTIES',section,[b]).
408 keyword('REFINEMENT',section,[b]).
409 keyword('REFINES',section,[b]).
410 keyword('SEES',section,[b]).
411 keyword('SETS',section,[b]).
412 keyword('SYSTEM',section,[b]).
413 keyword('USES',section,[b]).
414 keyword('VALUES',section,[b]).
415 keyword('VARIABLES',section,[b,tla]).
416 keyword('VARIANT',section,[b]).
417
418 % rules-dsl sections
419 keyword('ACTIVATION',section,[rules_dsl]).
420 keyword('BODY',section,[rules_dsl]).
421 keyword('CLASSIFICATION',section,[rules_dsl]).
422 keyword('COMPUTATION',section,[rules_dsl]).
423 keyword('COUNTEREXAMPLE',section,[rules_dsl]).
424 keyword('DEPENDS_ON_COMPUTATION',section,[rules_dsl]).
425 keyword('DEPENDS_ON_RULE',section,[rules_dsl]).
426 keyword('DEFINE',section,[rules_dsl]).
427 keyword('DUMMY_VALUE',section,[rules_dsl]).
428 keyword('ERROR_TYPE',section,[rules_dsl]).
429 keyword('ERROR_TYPES',section,[rules_dsl]).
430 keyword('FOR',section,[rules_dsl]).
431 keyword('FUNCTION',section,[rules_dsl]).
432 keyword('ON_SUCCESS',section,[rules_dsl]).
433 keyword('POSTCONDITION',section,[rules_dsl]).
434 keyword('PRECONDITION',section,[rules_dsl]).
435 keyword('REFERENCES',section,[rules_dsl]).
436 keyword('REPLACES',section,[rules_dsl]).
437 keyword('RULE_FAIL',section,[rules_dsl]).
438 keyword('RULE_FORALL',section,[rules_dsl]).
439 keyword('RULE',section,[rules_dsl]).
440 keyword('RULEID',section,[rules_dsl]).
441 keyword('RULES_MACHINE',section,[rules_dsl]).
442 keyword('TAGS',section,[rules_dsl]).
443 keyword('TYPE',section,[rules_dsl]).
444 keyword('UNCHECKED',section,[rules_dsl]).
445 keyword('VALUE',section,[rules_dsl]).
446
447
448 % TODO: check if these below are available within expressions:
449 keyword('DISABLED_RULE',section,[rules_dsl]).
450 keyword('FAILED_RULE',section,[rules_dsl]).
451 keyword('FAILED_RULE_ERROR_TYPE',section,[rules_dsl]).
452 keyword('FAILED_RULE_ALL_ERROR_TYPES',section,[rules_dsl]).
453 keyword('GET_RULE_COUNTEREXAMPLES',section,[rules_dsl]).
454 keyword('NOT_CHECKED_RULE',section,[rules_dsl]).
455 keyword('STRING_FORMAT',section,[rules_dsl]).
456 keyword('SUCCEEDED_RULE',section,[rules_dsl]).
457 keyword('SUCCEEDED_RULE_ERROR_TYPE',section,[rules_dsl]).
458
459
460 keyword('@desc',pragma,[b]).
461 keyword('@file',pragma,[b]).
462 keyword('@generated',pragma,[b]).
463 keyword('@import-package',pragma,[b]).
464 keyword('@label',pragma,[b]).
465 keyword('@package',pragma,[b]).
466 keyword('@symbolic',pragma,[b]).
467
468 % TLA sections
469 keyword('ASSUME',section,[tla]).
470 keyword('ASSUMPTION',section,[tla]).
471 keyword('AXIOM',section,[tla]).
472 keyword('CONSTANT',section,[tla]).
473 keyword('LOCAL',section,[tla]).
474 keyword('INSTANCE',section,[tla]).
475 keyword('MODULE',section,[tla]).
476 keyword('THEOREM',section,[tla]).
477
478 keyword('IF',_,[b,tla]).
479 keyword('THEN',_,[b,tla]).
480 keyword('ELSE',_,[b,tla]).
481 keyword('ELSIF',_,[b]).
482 keyword('LET',_,[b,tla]).
483 keyword('BE',_,[b]).
484 keyword('IN',_,[b,tla]).
485 keyword('END',_,[b,tla]).
486
487 % TLA expression keywords
488 keyword('BOOLEAN',expr,[tla]).
489 keyword('Cardinality',expr,[tla]).
490 keyword('CHOOSE',expr,[tla]).
491 keyword('DOMAIN',expr,[tla]).
492 keyword('ENABLED',expr,[tla]).
493 keyword('EXCEPT',expr,[tla]).
494 keyword('SUBSET',expr,[tla]).
495 keyword('UNCHANGED',expr,[tla]).
496 keyword('UNION',expr,[tla]).
497
498 % Alloy sections
499 keyword('abstract',section,[alloy]).
500 keyword('assert',section,[alloy]).
501 keyword('check',section,[alloy]).
502 keyword('extends',section,[alloy]).
503 keyword('fact',section,[alloy]).
504 keyword('fun',section,[alloy]).
505 keyword('module',section,[alloy]).
506 keyword('open',section,[alloy]).
507 keyword('pred',section,[alloy]).
508 keyword('run',section,[alloy]).
509 keyword('sig',section,[alloy]).
510
511
512 keyword('div',expr,[alloy]).
513 keyword('minus',expr,[alloy]).
514 keyword('else',expr,[alloy]).
515 keyword('iden',expr,[alloy]).
516 keyword('let',expr,[alloy]).
517 keyword('mul',expr,[alloy]).
518 keyword('plus',expr,[alloy]).
519 keyword('rem',expr,[alloy]).
520 keyword('sum',expr,[alloy]).
521 keyword('univ',expr,[alloy]).
522
523 keyword('all',predicate,[alloy]).
524 keyword('disjoint',predicate,[alloy]).
525 keyword('iff',predicate,[alloy]).
526 keyword('implies',predicate,[alloy]).
527 keyword('lone',predicate,[alloy]).
528 keyword('not',predicate,[alloy]).
529 keyword('no',predicate,[alloy]).
530 keyword('none',predicate,[alloy]).
531 keyword('one',predicate,[alloy]).
532 keyword('or',predicate,[alloy]).
533 keyword('some',predicate,[alloy]).
534 keyword('set',expr,[alloy]).
535
536 % SVG
537
538 get_all_svg_classes(SList) :- findall(A,is_svg_shape_class(A),List), sort(List,SList).
539
540 is_svg_shape_class(a).
541 is_svg_shape_class(animate). % can be a child of other elements
542 is_svg_shape_class(animateMotion). % can be a child of other elements
543 is_svg_shape_class(animateTransform). % can be a child of other elements
544 is_svg_shape_class(circle).
545 is_svg_shape_class(clipPath).
546 is_svg_shape_class(defs).
547 is_svg_shape_class(desc).
548 is_svg_shape_class(ellipse).
549 is_svg_shape_class(filter).
550 is_svg_shape_class(foreignObject). % can have HTML as children, body, table, tr, th, td
551 is_svg_shape_class(g). % group
552 is_svg_shape_class(image). % SVG files displayed with <image> cannot be interactive, include dynamic elements with <use>
553 is_svg_shape_class(line).
554 is_svg_shape_class(marker).
555 is_svg_shape_class(mask).
556 is_svg_shape_class(mpath).
557 is_svg_shape_class(path).
558 is_svg_shape_class(pattern).
559 is_svg_shape_class(polygon).
560 is_svg_shape_class(polyline).
561 is_svg_shape_class(rect).
562 is_svg_shape_class(script).
563 is_svg_shape_class(set).
564 is_svg_shape_class(style).
565 is_svg_shape_class(svg).
566 is_svg_shape_class(symbol).
567 is_svg_shape_class(text).
568 is_svg_shape_class(title). % useful when adding as children to other objects
569 is_svg_shape_class(tspan).
570 is_svg_shape_class(use).
571 is_svg_shape_class(view).
572 is_svg_shape_class(viewport).
573 % Note: one can also create <svg>, ... and HTML tags such as with document.createElementNS
574 % Note: script and title are also HTML tags
575
576 get_all_svg_attributes(SList) :- findall(A,is_svg_attribute(A),List), sort(List,SList).
577
578 % virtual attributes processed by VisB
579 is_virtual_svg_attribute(children).
580 is_virtual_svg_attribute(group_id). % also works like parent_id and can be used to attach animate objects
581 is_virtual_svg_attribute(hovers).
582 is_virtual_svg_attribute(svg_class).
583 is_virtual_svg_attribute(text).
584 is_virtual_svg_attribute(title).
585
586
587 is_svg_attribute_with_fixed_values('font-style', [normal, italic, oblique]).
588 % Note: bold and bolder not allowed; font-weight should be used for this
589 is_svg_attribute_with_fixed_values('text-anchor', [start , middle , end]).
590 is_svg_attribute_with_fixed_values('alignment-baseline',
591 [auto, baseline, before-edge, text-before-edge, middle, central,
592 after-edge, text-after-edge, ideographic, alphabetic, hanging, mathematical, top, center, bottom ]).
593 is_svg_attribute_with_fixed_values('dominant-baseline',
594 [auto, alphabetic, ideographic, middle, central, mathematical, hanging, 'text-bottom', 'text-top']).
595 is_svg_attribute_with_fixed_values('shape-rendering',
596 [auto, optimizeSpeed, crispEdges, geometricPrecision]).
597 is_svg_attribute_with_fixed_values('text-rendering',
598 [auto, optimizeSpeed, optimizeLegibility, geometricPrecision]).
599 is_svg_attribute_with_fixed_values('visibility',
600 [collapse,hidden,visible]).
601
602 % succeed if SVG attribute has a fixed list of possible values, possibly with an alternative
603 is_svg_attribute_with_fixed_text_values(Name,ListofTextValues,Alternative) :-
604 Alternative=no_alternative,
605 is_svg_attribute_with_fixed_values(Name,ListofTextValues).
606 is_svg_attribute_with_fixed_text_values('font-weight',[bold,bolder,lighter,normal],number).
607
608 % use this to check alternative from is_svg_attribute_with_fixed_text_values
609 check_svg_attribute_text_alternative(number,Atom) :- arg_is_number(Atom,_).
610
611 % errors where a value is used on the wrong attribute
612 fix_svg_attribute_based_on_value(fill,Val,Attr) :- infer_font_attr(Val,Attr).
613 fix_svg_attribute_based_on_value(Attr,Value,NewAttr) :- font_attr(Attr),
614 infer_font_or_fill_attr(Value,NewAttr), NewAttr \= Attr.
615
616 font_attr('font-family').
617 font_attr('font-size').
618 font_attr('font-style').
619 font_attr('font-weight').
620
621 infer_font_attr(bolder,'font-weight').
622 infer_font_attr(bold,'font-weight').
623 infer_font_attr(lighter,'font-weight').
624 infer_font_attr(italic,'font-style').
625 infer_font_attr(oblique,'font-style').
626
627 infer_font_or_fill_attr(Val,NewAttr) :- infer_font_attr(Val,NewAttr).
628 infer_font_or_fill_attr(Col,'fill') :- check_is_svg_color_name(Col).
629
630
631 % should be used instead of empty string '' by users:
632 svg_attribute_default_value('font-style','normal').
633 svg_attribute_default_value('font-weight','normal').
634
635
636 % first list of svg attributes which are not number or color attributes
637 is_svg_attribute('alignment-baseline'). % auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | top | center | bottom (this controls vertical alignment; see also text-anchor)
638 is_svg_attribute(attributeName). % from animate / animateTransform
639 is_svg_attribute(attributeType). % from animate
640 is_svg_attribute(begin). % from animate
641 is_svg_attribute(children). % virtual attribute of VisB
642 is_svg_attribute(class).
643 is_svg_attribute('clip-path').
644 is_svg_attribute('clip-rule').
645 is_svg_attribute('color-rendering').
646 is_svg_attribute(cursor).
647 is_svg_attribute(d). % path
648 is_svg_attribute(display).
649 is_svg_attribute(dur). % from animate
650 is_svg_attribute('dominant-baseline'). % auto | text-bottom | alphabetic | ideographic | middle | central | mathematical | hanging | text-top (this controls vertical alignment; see also text-anchor)
651 is_svg_attribute('fill-opacity').
652 is_svg_attribute('fill-rule').
653 is_svg_attribute('filter').
654 is_svg_attribute('flood-opacity').
655 is_svg_attribute('font-family').
656 % font-size is below under number attributes
657 is_svg_attribute('font-style'). % normal | italic | oblique
658 is_svg_attribute('font-variant').
659 is_svg_attribute('font-weight'). % normal | bold | bolder | lighter | <number>
660 is_svg_attribute(from).
661 is_svg_attribute(group_id). % virtual attribute of VisB
662 is_svg_attribute(hovers). % virtual attribute of VisB
663 is_svg_attribute('href'). % use
664 is_svg_attribute(id).
665 is_svg_attribute('lengthAdjust'). % spacing | spacingAndGlyphs for text
666 is_svg_attribute('marker-end').
667 is_svg_attribute('marker-start').
668 is_svg_attribute(mask).
669 % Note: name is a deprecated SVG attribute
670 is_svg_attribute(overflow). % for text, foreigObject, ...
671 is_svg_attribute(path).
672 is_svg_attribute('pointer-events').
673 is_svg_attribute(points). % polyline, polygon
674 is_svg_attribute(preserveAspectRatio).
675 is_svg_attribute(radius).
676 is_svg_attribute(repeatDur).
677 is_svg_attribute(repeatCount). % from animate
678 is_svg_attribute(restart).
679 is_svg_attribute(rotate).
680 is_svg_attribute(scale).
681 is_svg_attribute(seed).
682 is_svg_attribute('shape-rendering'). % auto | optimizeSpeed | crispEdges | geometricPrecision
683 is_svg_attribute(startoffset).
684 is_svg_attribute(stdDeviation).
685 is_svg_attribute(stitchTiles).
686 is_svg_attribute(stroke).
687 is_svg_attribute('stroke-dasharray').
688 is_svg_attribute('stroke-dashoffset').
689 is_svg_attribute('stroke-linecap'). % butt (default), round, square
690 is_svg_attribute('stroke-linejoin').
691 is_svg_attribute('stroke-miterlimit').
692 is_svg_attribute(style).
693 is_svg_attribute(surfaceScale).
694 is_svg_attribute(svg_class). % virtual attribute of VisB
695 is_svg_attribute(systemLanguage).
696 is_svg_attribute(tableValues).
697 is_svg_attribute(text). % specially processed by VisB as well
698 is_svg_attribute('text-anchor'). % start | middle | end
699 is_svg_attribute('text-decoration'). % underline | line-through, ....
700 is_svg_attribute('text-rendering'). % auto | optimizeSpeed | optimizeLegibility | geometricPrecision
701 is_svg_attribute(textLength).
702 is_svg_attribute(title). % virtual attribute of VisB
703 is_svg_attribute(to).
704 is_svg_attribute(transform).
705 is_svg_attribute(type).
706 is_svg_attribute(values). % from animate
707 is_svg_attribute(viewBox). % e.g. for symbol
708 is_svg_attribute(visibility).
709 is_svg_attribute('vector-effect').
710 is_svg_attribute('word-spacing').
711 is_svg_attribute('xlink:href').
712 is_svg_attribute(X) :- is_svg_number_attribute(X,_).
713 is_svg_attribute(X) :- is_svg_color_attribute(X).
714 % TODO: complete
715
716 is_svg_color_attribute(color). % can be applied to any element; provides currentcolor value
717 is_svg_color_attribute(fill). % can be applied to [circle,ellipse,path,polygon,polyline,rect,text,tref,tspan]).
718 is_svg_color_attribute(stroke). % can also be applied to all shapes we use circle, ...
719 is_svg_color_attribute('flood-color').
720 is_svg_color_attribute('lighting-color').
721 is_svg_color_attribute('stop-color').
722
723 is_svg_number_attribute(cx,[circle, ellipse, radialGradient]).
724 is_svg_number_attribute(cy,[circle, ellipse, radialGradient]).
725 is_svg_number_attribute(dx,_).
726 is_svg_number_attribute(dy,_).
727 is_svg_number_attribute(opacity,_).
728 is_svg_number_attribute(pathLength,_).
729 is_svg_number_attribute(x,[foreignObject,image,pattern,rect,svg,text,tspan,use]). % many more: cursor, image, mask, ...
730 is_svg_number_attribute(y,[foreignObject,image,pattern,rect,svg,text,tspan,use]).
731 is_svg_number_attribute(x1,[line,linearGradient]).
732 is_svg_number_attribute(x2,[line,linearGradient]).
733 is_svg_number_attribute(y1,[line,linearGradient]).
734 is_svg_number_attribute(y2,[line,linearGradient]).
735 is_svg_number_attribute('font-size',_).
736 is_svg_number_attribute('stop-opacity',_).
737 is_svg_number_attribute('stroke-opacity',_).
738 is_svg_number_attribute('stroke-width',_).
739 is_svg_number_attribute(height,[foreignObject,image,pattern,rect,svg,use]). % others like mask ,...
740 is_svg_number_attribute(width, [foreignObject,image,pattern,rect,svg,use]).
741 is_svg_number_attribute(r,[circle, radialGradient]).
742 is_svg_number_attribute(rx,[ellipse,rect]).
743 is_svg_number_attribute(ry,[ellipse,rect]).
744 is_svg_number_attribute(tabindex,_).
745 is_svg_number_attribute(z,_).
746
747 :- use_module(kernel_strings,[atom_to_lowercase/2]).
748 check_is_svg_color_name(Atom) :-
749 (is_svg_color_name(Atom) -> true
750 ; atom_to_lowercase(Atom,LCAtom),
751 is_svg_color_name(LCAtom)).
752
753 % Note: SVG color values are case-insensitive; below is only the lower case version
754 % other valid SVG colors are
755 % #808080 rgb(127,127,127)
756 is_svg_color_name(aliceblue).
757 is_svg_color_name(antiquewhite).
758 is_svg_color_name(aqua).
759 is_svg_color_name(aquamarine).
760 is_svg_color_name(azure).
761 is_svg_color_name(beige).
762 is_svg_color_name(bisque).
763 is_svg_color_name(black).
764 is_svg_color_name(blanchedalmond).
765 is_svg_color_name(blue).
766 is_svg_color_name(blueviolet).
767 is_svg_color_name(brown).
768 is_svg_color_name(burlywood).
769 is_svg_color_name(cadetblue).
770 is_svg_color_name(chartreuse).
771 is_svg_color_name(chocolate).
772 is_svg_color_name(coral).
773 is_svg_color_name(cornflowerblue).
774 is_svg_color_name(cornsilk).
775 is_svg_color_name(crimson).
776 is_svg_color_name(currentColor). % use the value of the color CSS property
777 is_svg_color_name(cyan).
778 is_svg_color_name(darkblue).
779 is_svg_color_name(darkcyan).
780 is_svg_color_name(darkgoldenrod).
781 is_svg_color_name(darkgray).
782 is_svg_color_name(darkgreen).
783 is_svg_color_name(darkgrey).
784 is_svg_color_name(darkkhaki).
785 is_svg_color_name(darkmagenta).
786 is_svg_color_name(darkolivegreen).
787 is_svg_color_name(darkorange).
788 is_svg_color_name(darkorchid).
789 is_svg_color_name(darkred).
790 is_svg_color_name(darksalmon).
791 is_svg_color_name(darkseagreen).
792 is_svg_color_name(darkslateblue).
793 is_svg_color_name(darkslategray).
794 is_svg_color_name(darkslategrey).
795 is_svg_color_name(darkturquoise).
796 is_svg_color_name(darkviolet).
797 is_svg_color_name(deeppink).
798 is_svg_color_name(deepskyblue).
799 is_svg_color_name(dimgray).
800 is_svg_color_name(dimgrey).
801 is_svg_color_name(dodgerblue).
802 is_svg_color_name(firebrick).
803 is_svg_color_name(floralwhite).
804 is_svg_color_name(forestgreen).
805 is_svg_color_name(fuchsia).
806 is_svg_color_name(gainsboro).
807 is_svg_color_name(ghostwhite).
808 is_svg_color_name(gold).
809 is_svg_color_name(goldenrod).
810 is_svg_color_name(gray).
811 is_svg_color_name(green).
812 is_svg_color_name(greenyellow).
813 is_svg_color_name(grey).
814 is_svg_color_name(honeydew).
815 is_svg_color_name(hotpink).
816 is_svg_color_name(indianred).
817 is_svg_color_name(indigo).
818 is_svg_color_name(ivory).
819 is_svg_color_name(khaki).
820 is_svg_color_name(lavender).
821 is_svg_color_name(lavenderblush).
822 is_svg_color_name(lawngreen).
823 is_svg_color_name(lemonchiffon).
824 is_svg_color_name(lightblue).
825 is_svg_color_name(lightcoral).
826 is_svg_color_name(lightcyan).
827 is_svg_color_name(lightgoldenrodyellow).
828 is_svg_color_name(lightgray).
829 is_svg_color_name(lightgreen).
830 is_svg_color_name(lightgrey).
831 is_svg_color_name(lightpink).
832 is_svg_color_name(lightsalmon).
833 is_svg_color_name(lightseagreen).
834 is_svg_color_name(lightskyblue).
835 is_svg_color_name(lightslategray).
836 is_svg_color_name(lightslategrey).
837 is_svg_color_name(lightsteelblue).
838 is_svg_color_name(lightyellow).
839 is_svg_color_name(lime).
840 is_svg_color_name(limegreen).
841 is_svg_color_name(linen).
842 is_svg_color_name(magenta).
843 is_svg_color_name(maroon).
844 is_svg_color_name(mediumaquamarine).
845 is_svg_color_name(mediumblue).
846 is_svg_color_name(mediumorchid).
847 is_svg_color_name(mediumpurple).
848 is_svg_color_name(mediumseagreen).
849 is_svg_color_name(mediumslateblue).
850 is_svg_color_name(mediumspringgreen).
851 is_svg_color_name(mediumturquoise).
852 is_svg_color_name(mediumvioletred).
853 is_svg_color_name(midnightblue).
854 is_svg_color_name(mintcream).
855 is_svg_color_name(mistyrose).
856 is_svg_color_name(moccasin).
857 is_svg_color_name(navajowhite).
858 is_svg_color_name(navy).
859 is_svg_color_name(none).
860 is_svg_color_name(oldlace).
861 is_svg_color_name(olive).
862 is_svg_color_name(olivedrab).
863 is_svg_color_name(orange).
864 is_svg_color_name(orangered).
865 is_svg_color_name(orchid).
866 is_svg_color_name(palegoldenrod).
867 is_svg_color_name(palegreen).
868 is_svg_color_name(paleturquoise).
869 is_svg_color_name(palevioletred).
870 is_svg_color_name(papayawhip).
871 is_svg_color_name(peachpuff).
872 is_svg_color_name(peru).
873 is_svg_color_name(pink).
874 is_svg_color_name(plum).
875 is_svg_color_name(powderblue).
876 is_svg_color_name(purple).
877 is_svg_color_name(red).
878 is_svg_color_name(rosybrown).
879 is_svg_color_name(royalblue).
880 is_svg_color_name(saddlebrown).
881 is_svg_color_name(salmon).
882 is_svg_color_name(sandybrown).
883 is_svg_color_name(seagreen).
884 is_svg_color_name(seashell).
885 is_svg_color_name(sienna).
886 is_svg_color_name(silver).
887 is_svg_color_name(skyblue).
888 is_svg_color_name(slateblue).
889 is_svg_color_name(slategray).
890 is_svg_color_name(slategrey).
891 is_svg_color_name(snow).
892 is_svg_color_name(springgreen).
893 is_svg_color_name(steelblue).
894 is_svg_color_name(tan).
895 is_svg_color_name(teal).
896 is_svg_color_name(thistle).
897 is_svg_color_name(tomato).
898 is_svg_color_name(turquoise).
899 is_svg_color_name(violet).
900 is_svg_color_name(wheat).
901 is_svg_color_name(white).
902 is_svg_color_name(whitesmoke).
903 is_svg_color_name(yellow).
904 is_svg_color_name(yellowgreen).
905
906 % TODO: maybe provide list with parameters to instantiate a template?
907 is_svg_template(circle,
908 'rec(svg_class:"circle",r:RADIUS,cx:CX,cy:CY,fill:"red",`stroke-width`:0.2)').
909 is_svg_template(ellipse,
910 'rec(svg_class:"ellipse",cx:X,cy:Y,rx:RX,ry:RY,fill:"purple")').
911 is_svg_template(line,
912 'rec(svg_class:"line",x1:X1,y1:Y1,x2:X2,y2:Y2,stroke:"blue",`stroke-width`:0.2)').
913 is_svg_template(rect,
914 'rec(svg_class:"rect",stroke:"lightgray",fill:"blue",`stroke-width`:0.5,`stroke-dasharray`:"0.4 0.9",x:X,y:Y,width:W,height:H)').
915 is_svg_template(polygon,
916 'rec(svg_class:"polygon",stroke:"black",`stroke-width`:0.1,fill:"gray",transform:"translate(0,2.2)",points:[(0,0),(10,10),(0,10)])').
917 is_svg_template(polyline,
918 'rec(svg_class:"polyline",stroke:"black",fill:"white",points:UNION(i).(i:-10..10|{i|->real(i)/2.0}))').
919 is_svg_template(text,
920 'rec(svg_class:"text",x:X,y:Y,`font-size`:9.0,`alignment-baseline`:"middle",`text-anchor`:"end",text:```MYTEXT ${BEXPR}```)').
921 is_svg_template(path,'rec(svg_class:"path",`id`:"path1",stroke:"black",d:"M12 43 L12 54")').
922 is_svg_template(group,'rec(svg_class:"g",`id`:"group1",children:{"child1","child2"})').
923 is_svg_template(use,'rec(svg_class:"use",href:"#group1")').
924 is_svg_template(script,'rec(svg_class:"script", text:```myJSprocedure(${x});```)').
925 is_svg_template(animate,'rec(svg_class:"animate",attributeName:"cx",to:x,dur:"0.5s",fill:"freeze",begin:"indefinite")').
926 is_svg_template(foreignObject,'rec(svg_class:"foreignObject",x:X,y:Y,width:W,height:H,text:```<input id="${MYID}" type="text" style="width:100%; height:100%; box-sizing:border-box;"/>```)').
927
928 is_svg_template(visb_svg_box,'VISB_SVG_BOX == rec(width:WW,height:HH,viewBox:"minx miny w h")').
929 % ----------------------------
930
931 % DOT
932
933 :- use_module(preferences,[tk_color_name/1]).
934 is_dot_color_name(N) :-
935 tk_color_name(N). % simply use Tk color names for dot
936
937 get_all_dot_attributes(SList) :- findall(A,is_dot_attribute(A),List), sort(List,SList).
938
939 % list of known synonyms of Dot attributes and how to translate them to SVG object attributes
940 % used to be called dot2svg_attribute but also does other corrections
941
942 % dot attributes which do not exist in SVG:
943 fix_svg_attribute(fillcolor,fill).
944 fix_svg_attribute(fillcolour,fill).
945 fix_svg_attribute('fill-color',fill).
946 fix_svg_attribute('fill-colour',fill).
947 fix_svg_attribute(fill_color,fill).
948 fix_svg_attribute(fill_colour,fill).
949 fix_svg_attribute(fontname,'font-family').
950 fix_svg_attribute('font-name','font-family').
951 fix_svg_attribute(font_name,'font-family').
952 fix_svg_attribute(fontcolor,fill). % one should probably use fill to colour text
953 fix_svg_attribute(fontcolour,fill).
954 fix_svg_attribute('font-color',fill). % not really a dot attribute, but a typical misspelling
955 fix_svg_attribute('font-colour',fill).
956 fix_svg_attribute(font_color,fill).
957 fix_svg_attribute(font_colour,fill).
958 % typical errors:
959 fix_svg_attribute(visible,visibility).
960 fix_svg_attribute(border,stroke). % HTML table has this attribute, Copilot suggests this for SVG ;-)
961 fix_svg_attribute('stroke-dash-array','stroke-dasharray').
962 fix_svg_attribute(stroke_dash_array,'stroke-dasharray').
963
964 % list of Dot shapes which are not valid SVG classes and which SVG concept they map to
965 dotshape2svg_class('Mcircle',circle).
966 dotshape2svg_class(doublecircle,circle).
967 dotshape2svg_class(egg,ellipse).
968 dotshape2svg_class(oval,ellipse).
969 dotshape2svg_class('Msquare',rect).
970 dotshape2svg_class(box,rect).
971 dotshape2svg_class(box3d,rect).
972 dotshape2svg_class(rectangle,rect).
973 dotshape2svg_class(square,rect).
974 dotshape2svg_class('Mdiamond',polygon).
975 dotshape2svg_class(diamond,polygon).
976 dotshape2svg_class(doubleoctagon,polygon).
977 dotshape2svg_class(hexagon,polygon).
978 dotshape2svg_class(house,polygon).
979 dotshape2svg_class(invhouse,polygon).
980 dotshape2svg_class(invtrapezium,polygon).
981 dotshape2svg_class(invtriangle,polygon).
982 dotshape2svg_class(octagon,polygon).
983 dotshape2svg_class(parallelogram,polygon).
984 dotshape2svg_class(pentagon,polygon).
985 dotshape2svg_class(septagon,polygon).
986 dotshape2svg_class(trapezium,polygon).
987 dotshape2svg_class(triangle,polygon).
988 dotshape2svg_class(tripleoctagon,polygon).
989 dotshape2svg_class(note,text).
990 dotshape2svg_class(plaintext,text).
991 dotshape2svg_class(larrow,polyline).
992 dotshape2svg_class(rarrow,polyline).
993
994
995 % see https://graphviz.org/docs/nodes/, comments taken from there
996 is_dot_attribute(area).
997 is_dot_attribute(class). % Classnames to attach to the node, edge, graph, or cluster's SVG element. For svg only.
998 is_dot_attribute(color). % Basic drawing color for graphics, not text.
999 is_dot_attribute(colorscheme). % A color scheme namespace: the context for interpreting color names.
1000 is_dot_attribute(comment). % Comments are inserted into output.
1001 is_dot_attribute(distortion). % Distortion factor for shape=polygon.
1002 is_dot_attribute(fillcolor). % Color used to fill the background of a node or cluster.
1003 is_dot_attribute(fixedsize).
1004 is_dot_attribute(fontcolor). % Color used for text.
1005 is_dot_attribute(fontname). % Font used for text.
1006 is_dot_attribute(fontsize). % Font size, in points, used for text.
1007 is_dot_attribute(gradientangle). % If a gradient fill is being used, this determines the angle of the fill.
1008 is_dot_attribute(group). % Name for a group of nodes, for bundling edges avoiding crossings. For dot only.
1009 is_dot_attribute(height). % Height of node, in inches.
1010 is_dot_attribute(href). % Synonym for URL. For map, postscript, svg only.
1011 is_dot_attribute(id). % Identifier for graph objects. For map, postscript, svg only.
1012 is_dot_attribute(image).
1013 is_dot_attribute(imagepos).
1014 is_dot_attribute(imagescale).
1015 is_dot_attribute(label). % Text label attached to objects.
1016 is_dot_attribute(labelloc). % Vertical placement of labels for nodes, root graphs and clusters.
1017 is_dot_attribute(layer). % Specifies layers in which the node, edge or cluster is present.
1018 %is_dot_attribute(margin). % For graphs, this sets x and y margins of canvas, in inches.
1019 is_dot_attribute(nojustify). % Whether to justify multiline text vs the previous text line (rather than the side of the container).
1020 is_dot_attribute(ordering). % default, out, in Constrains the left-to-right ordering of node edges. For dot only.
1021 is_dot_attribute(orientation).% node shape rotation angle, or graph orientation.
1022 is_dot_attribute(penwidth). % Specifies the width of the pen, in points, used to draw lines and curves.
1023 is_dot_attribute(peripheries). % Set number of peripheries used in polygonal shapes and cluster boundaries.
1024 is_dot_attribute(pin).
1025 is_dot_attribute(pos).
1026 is_dot_attribute(rects).
1027 is_dot_attribute(regular).
1028 is_dot_attribute(root).
1029 is_dot_attribute(samplepoints). % Gives the number of points used for a circle/ellipse node.
1030 is_dot_attribute(shape). % Sets the shape of a node.
1031 is_dot_attribute(shapefile).
1032 is_dot_attribute(showboxes). % Print guide boxes for debugging. For dot only.
1033 is_dot_attribute(style). % Set style information for components of the graph.
1034 is_dot_attribute(skew). % Skew factor for shape=polygon.
1035 is_dot_attribute(sides). % Number of sides when shape=polygon.
1036 is_dot_attribute(sortv). % Sort order of graph components for ordering packmode packing.
1037 is_dot_attribute(target). % If the object has a URL, this attribute determines which window of the browser is used for the URL. For map, svg only.
1038 is_dot_attribute(tooltip). % Tooltip (mouse hover text) attached to the node, edge, cluster, or graph
1039 is_dot_attribute('URL').
1040 is_dot_attribute(vertices).
1041 is_dot_attribute(width). % Width of node, in inches.
1042 is_dot_attribute(xlabel). % External label for a node or edge.
1043 is_dot_attribute(xlp). % Position of an exterior label, in points. For write only.
1044 is_dot_attribute(z). % Z-coordinate value for 3D layouts and displays.
1045
1046 % additional edge attributes from https://graphviz.org/docs/edges/
1047 is_dot_attribute(arrowhead). % Style of arrowhead on the head node of an edge.
1048 is_dot_attribute(arrowsize). % Multiplicative scale factor for arrowheads.
1049 is_dot_attribute(arrowtail). % Style of arrowhead on the tail node of an edge.
1050 is_dot_attribute(constraint). % If false, the edge is not used in ranking the nodes. For dot only.
1051 is_dot_attribute(decorate). % Whether to connect the edge label to the edge with a line.
1052 is_dot_attribute(dir). % Edge type for drawing arrowheads. (forward, back, both, none)
1053 is_dot_attribute(headlabel). % Text label to be placed near head of edge.
1054 is_dot_attribute(headport). % Indicates where on the head node to attach the head of the edge.
1055 is_dot_attribute(labelangle).
1056 is_dot_attribute(labeldistance).
1057 is_dot_attribute(labelfloat).
1058 is_dot_attribute(labelfontcolor). % Color used for headlabel and taillabel.
1059 is_dot_attribute(labelfontname). % Font for headlabel and taillabel.
1060 is_dot_attribute(labelfontsize). % Font size of headlabel and taillabel.
1061 is_dot_attribute(len).
1062 is_dot_attribute(lhead). % Logical head of an edge. For dot only.
1063 is_dot_attribute(minlen). % Minimum edge length (rank difference between head and tail). For dot only.
1064 is_dot_attribute(taillabel). % Text label to be placed near tail of edge.
1065 is_dot_attribute(tailport). % Indicates where on the tail node to attach the tail of the edge.
1066 is_dot_attribute(weight). % Weight of edge. In dot, the heavier the weight, the shorter, straighter and more vertical the edge is.
1067
1068 % for graphs:
1069 is_dot_attribute(bgcolor).
1070 % https://graphviz.org/doc/info/colors.html#brewer
1071 % ex: accent8, blue9, brbg11, bugn9, bupu9, dark28, gnbu9, greeens9, greys9, oranges9, set312, set39, spectral11
1072 % does not work as graph attribute, needs to be set as default node/edge attribute or added to nodes/edges
1073 is_dot_attribute(compound). % If true, allow edges between clusters. For dot only, relevant for lhead/ltail edge attrs
1074 is_dot_attribute(concentrate). % If true, use edge concentrators.
1075 is_dot_attribute(landscape). % If true, the graph is rendered in landscape mode.
1076 is_dot_attribute(layout). % Which layout engine to use. dot, neato, circo, fdp, sfdp, twopi, patchwork, nop, nop2
1077 is_dot_attribute(mode). % Technique for optimizing the layout
1078 %is_dot_attribute(ordering). % declared for nodes above, Constrains the left-to-right ordering of node edges. For dot only. out, in
1079 %is_dot_attribute(orientation). % declared for nodes above, node shape rotation angle, or graph orientation
1080 is_dot_attribute(outputorder). % Specify order in which nodes and edges are drawn
1081 is_dot_attribute(overlap). % Determines if and how node overlaps should be removed
1082 is_dot_attribute(rankdir). % Sets direction of graph layout. For dot only. TB, BT, LR, RL
1083 is_dot_attribute(ranksep). % Specifies separation between ranks. For dot, twopi only.
1084 is_dot_attribute(ratio). % Sets the aspect ratio (drawing height/drawing width) for the drawing.
1085 is_dot_attribute(scale). % Scales layout by the given factor after the initial layout
1086 is_dot_attribute(size). % Maximum width and height of drawing, in inches
1087 is_dot_attribute(splines).
1088
1089 is_dot_attribute(directed). % virtual attribute -> influences whether dot_graph_generator writes digraph or graph
1090 is_dot_attribute(strict). % virtual attribute -> influences whether dot_graph_generator writes strict digraph/graph
1091
1092 % -------------
1093
1094
1095 % HTML tags can e.g. appear as children of foreign_objects in SVG
1096 is_html_tag(a).
1097 is_html_tag(abbr).
1098 is_html_tag(acronym).
1099 is_html_tag(address).
1100 is_html_tag(applet).
1101 is_html_tag(area).
1102 is_html_tag(article).
1103 is_html_tag(aside).
1104 is_html_tag(audio).
1105 is_html_tag(b). % bold
1106 is_html_tag(base).
1107 is_html_tag(basefont).
1108 is_html_tag(bdi).
1109 is_html_tag(bdo).
1110 is_html_tag(big).
1111 is_html_tag(blockquote).
1112 is_html_tag(body).
1113 is_html_tag(br).
1114 is_html_tag(button). % clickable button
1115 is_html_tag(canvas).
1116 is_html_tag(caption).
1117 is_html_tag(center).
1118 is_html_tag(cite).
1119 is_html_tag(code).
1120 is_html_tag(col).
1121 is_html_tag(colgroup).
1122 is_html_tag(data).
1123 is_html_tag(datalist).
1124 is_html_tag(dd).
1125 is_html_tag(del). % deleted text
1126 is_html_tag(details).
1127 is_html_tag(dialog). % dialog or window
1128 is_html_tag(div).
1129 is_html_tag(dfn).
1130 is_html_tag(dl). % description list
1131 is_html_tag(dt).
1132 is_html_tag(em).
1133 is_html_tag(embed).
1134 is_html_tag(fieldset).
1135 is_html_tag(figcaption).
1136 is_html_tag(figure).
1137 is_html_tag(font).
1138 is_html_tag(footer).
1139 is_html_tag(form).
1140 is_html_tag(frame).
1141 is_html_tag(frameset).
1142 is_html_tag(h1).
1143 is_html_tag(h2).
1144 is_html_tag(h3).
1145 is_html_tag(h4).
1146 is_html_tag(h5).
1147 is_html_tag(h6).
1148 is_html_tag(head).
1149 is_html_tag(header).
1150 is_html_tag(hgroup).
1151 is_html_tag(hr). % horizontal rule
1152 is_html_tag(i). % italic
1153 is_html_tag(html).
1154 is_html_tag(iframe).
1155 is_html_tag(img).
1156 is_html_tag(input). % input field
1157 is_html_tag(ins). % inserted text
1158 is_html_tag(kbd). % keyboard input
1159 is_html_tag(label).
1160 is_html_tag(legend).
1161 is_html_tag(li).
1162 is_html_tag(link).
1163 is_html_tag(main).
1164 is_html_tag(map).
1165 is_html_tag(mark). % highlight text
1166 is_html_tag(meta).
1167 is_html_tag(metre). % shows scalar measurement within a range
1168 is_html_tag(nav).
1169 is_html_tag(noframes).
1170 is_html_tag(noscript).
1171 is_html_tag(object).
1172 is_html_tag(ol). % ordered list
1173 is_html_tag(optgroup).
1174 is_html_tag(option). % option in a select list
1175 is_html_tag(output).
1176 is_html_tag(p).
1177 is_html_tag(param).
1178 is_html_tag(picture).
1179 is_html_tag(pre).
1180 is_html_tag(progress). % shows completion progress of a task
1181 is_html_tag(q).
1182 is_html_tag(rp).
1183 is_html_tag(rt).
1184 is_html_tag(ruby).
1185 is_html_tag(s). % strikethrough
1186 is_html_tag(samp). % sample output
1187 is_html_tag(script).
1188 is_html_tag(section).
1189 is_html_tag(select). % dropdown list
1190 is_html_tag(small).
1191 is_html_tag(source).
1192 is_html_tag(span).
1193 is_html_tag(strike).
1194 is_html_tag(strong).
1195 is_html_tag(style).
1196 is_html_tag(summary).
1197 is_html_tag(sub). % subscript
1198 is_html_tag(sup). % superscript
1199 is_html_tag(svg).
1200 is_html_tag(table).
1201 is_html_tag(tbody).
1202 is_html_tag(td). % table data
1203 is_html_tag(template).
1204 is_html_tag(textarea). % multiline text input
1205 is_html_tag(tfoot).
1206 is_html_tag(th). % table header
1207 is_html_tag(thead).
1208 is_html_tag(time). % shows specific period in time or a range of time
1209 is_html_tag(title).
1210 is_html_tag(tr). % table row
1211 is_html_tag(track).
1212 is_html_tag(tt). % not supported in HTML 5
1213 is_html_tag(u). % underline
1214 is_html_tag(ul). % unordered list
1215 is_html_tag(var). % variables
1216 is_html_tag(video).
1217 is_html_tag(wbr).
1218
1219 % completely incomplete list :
1220 is_html_attribute(accesskey).
1221 is_html_attribute(class).
1222 is_html_attribute(contenteditable).
1223 is_html_attribute(contextmenu).
1224 is_html_attribute(dir).
1225 is_html_attribute(disabled). % for option,...
1226 is_html_attribute(draggable).
1227 is_html_attribute(enterkeyhing).
1228 is_html_attribute(hidden).
1229 is_html_attribute(href).
1230 is_html_attribute(id).
1231 is_html_attribute(inert).
1232 is_html_attribute(inputmode).
1233 is_html_attribute(label). % for option,...
1234 is_html_attribute(lang).
1235 is_html_attribute(media).
1236 is_html_attribute(onchange). % for Event attribute, e.g., for select
1237 is_html_attribute(onerror).
1238 is_html_attribute(onhaschange).
1239 is_html_attribute(onload).
1240 is_html_attribute(onmessage).
1241 is_html_attribute(popover).
1242 is_html_attribute(rel).
1243 is_html_attribute(selected). % for option,...
1244 is_html_attribute(spellcheck).
1245 is_html_attribute(style).
1246 is_html_attribute(tabindex).
1247 is_html_attribute(target). % for a
1248 is_html_attribute(title).
1249 is_html_attribute(translate).
1250 is_html_attribute(type). % for a
1251 is_html_attribute(value). % for option,...
1252
1253 % -------------
1254
1255 % some errors one could make, with a possible corrected id/keyword:
1256
1257 %suggested_alternative_id('RGAUSS','RNORMAL').
1258 %suggested_alternative_id('GAUSS','RNORMAL').
1259
1260 % -------------
1261
1262
1263 % translate_keywords:classical_b_keyword(K), \+ tools_matching:keyword(K,_,_). % Note: items is not a B keyword
1264 % TO DO: complete keywords for Alloy, TLA, Z minor modes; possibly add VisB/SVG and CUSTOM_GRAPH/GraphViz attributes
1265
1266 :- use_module(preferences,[eclipse_preference/2]).
1267 get_possible_preferences(SPrefs) :-
1268 findall(Pref,eclipse_preference(Pref,_),P),
1269 sort(P,SPrefs).
1270
1271 get_possible_preferences_matches_msg(String,FuzzyMatchMsg) :-
1272 get_possible_preferences(Prefs),
1273 ? if(get_possible_fuzzy_matches_and_completions_msg(String,Prefs,FuzzyMatchMsg),
1274 true,
1275 get_possible_inner_matches_msg(String,Prefs,FuzzyMatchMsg,lower_case_norm,all,no_decompose)). % also look for inner matches
1276
1277 :- use_module(specfile,[get_possible_language_specific_top_level_event/3]).
1278 :- use_module(bmachine,[b_is_operation_name/1, b_get_machine_operation/4]).
1279 get_possible_top_level_event_matches_msg(String,FuzzyMatchMsg) :-
1280 findall(Op,get_possible_language_specific_top_level_event(Op,_,_),Ops), sort(Ops,SOps),
1281 if(get_possible_fuzzy_matches_and_completions_msg(String,SOps,FuzzyMatchMsg),
1282 true,
1283 get_possible_inner_matches_msg(String,SOps,FuzzyMatchMsg)). % also look for inner matches
1284
1285 % also matches subsidiary (not top-level) operations
1286 get_possible_operation_matches_msg(OpName,FuzzyMatchMsg) :-
1287 findall(Name,b_get_machine_operation(Name,_Results,_Parameters,_),Ops), sort(Ops,SOps),
1288 if(get_possible_fuzzy_matches_and_completions_msg(OpName,SOps,FuzzyMatchMsg),
1289 true,
1290 if(get_possible_inner_matches_msg(OpName,SOps,FuzzyMatchMsg,no_norm,suffix_only,decompose), % first look for stricter matches
1291 true,
1292 get_possible_inner_matches_msg(OpName,SOps,FuzzyMatchMsg))).
1293
1294 get_possible_fuzzy_matches_and_completions_msg(String,AllIds,FuzzyMatchMsg) :-
1295 (get_possible_fuzzy_matches_msg(String,AllIds,FuzzyMatchMsg) ;
1296 get_possible_completions_msg(String,AllIds,FuzzyMatchMsg)).
1297
1298
1299 get_possible_fuzzy_matches_completions_and_inner_msg(String,AllIds,FuzzyMatchMsg) :-
1300 if(get_possible_fuzzy_matches_and_completions_msg(String,AllIds,FuzzyMatchMsg),
1301 true,
1302 get_possible_inner_matches_msg(String,AllIds,FuzzyMatchMsg)).
1303
1304
1305 get_possible_fuzzy_matches(ID,AllIDs,FuzzyMatches) :- atom(ID),!,
1306 atom_codes(ID,IDCodes),
1307 findall(Target,(member(Target,AllIDs),atom_codes(Target,TargetCodes),
1308 fuzzy_match_codes_lower_case(IDCodes,TargetCodes)),FuzzyMatches).
1309 get_possible_fuzzy_matches(ID,_,_) :-
1310 add_internal_error('Not an atom: ',get_possible_fuzzy_matches(ID,_,_)),fail.
1311
1312 % get possible matches as atom which can be used after phrase: Did you mean:
1313 get_possible_fuzzy_matches_msg(ID,AllIDs,Msg) :-
1314 get_possible_fuzzy_matches(ID,AllIDs,FuzzyMatches),
1315 get_match_msg(FuzzyMatches,Msg).
1316
1317 get_match_msg(FuzzyMatches,Msg) :-
1318 length(FuzzyMatches,Nr), Nr>0,
1319 get_msg(FuzzyMatches,Nr,Msg).
1320
1321 get_msg([Match],1,Res) :- !, Res=Match.
1322 get_msg(List,Nr,Msg) :- Nr < 6, !,
1323 ajoin_with_sep(List,',',Msg).
1324 get_msg([First|_],Nr,Msg) :- N1 is Nr-1,
1325 ajoin([First,' (',N1,' more matches)'],Msg).
1326
1327
1328
1329 % get possible completions as atom which can be used after phrase: Did you mean:
1330 get_possible_completions_msg(ID,SortedAllIDs,Msg) :-
1331 atom_codes(ID,IDCodes0),
1332 codes_to_lower_case(IDCodes0,IDCodes),
1333 findall(Target,(member(Target,SortedAllIDs),atom_codes(Target,TargetCodes),
1334 codes_to_lower_case(TargetCodes,TC2),
1335 prefix(TC2,IDCodes) % IDCodes is a prefix of the target
1336 ),Completions),
1337 get_match_msg(Completions,Msg).
1338
1339
1340 % get possible interior matches as atom which can be used after phrase: Did you mean:
1341 get_possible_inner_matches_msg(ID,SortedAllIDs,Msg) :-
1342 get_possible_inner_matches_msg(ID,SortedAllIDs,Msg,lower_case_norm,all,decompose).
1343
1344 % if LC=lower_case_norm we normalise target and source to lower_case before matching
1345 get_possible_inner_matches_msg(ID,SortedAllIDs,Msg,LC,SuffixOnly,DecomposeIDs) :-
1346 atom_codes(ID,IDCodes0),
1347 (DecomposeIDs=decompose -> decompose_codes_id(IDCodes0,IDCodes1) ; IDCodes1=IDCodes0),
1348 length(IDCodes1,Len), Len>3, % only do this if the string is long enough
1349 (LC=lower_case_norm -> codes_to_lower_case(IDCodes1,IDCodes) ; IDCodes=IDCodes1),
1350 findall(Target,(member(Target,SortedAllIDs),atom_codes(Target,TargetCodes),
1351 (LC=lower_case_norm -> codes_to_lower_case(TargetCodes,TC2) ; TC2=TargetCodes),
1352 % format('Looking for ~s inside ~s or vice-versa~n',[IDCodes,TC2]),
1353 (SuffixOnly \= suffix_only,
1354 sublist(IDCodes,TC2,_Before,_,_) -> true % Target TC2 is a sublist of ID
1355 ; (SuffixOnly=suffix_only -> AfterLength=0 ; true),
1356 sublist(TC2,IDCodes,_Bef,_Len,AfterLength) % ID is a sublist of the target
1357 )
1358 ),Completions),
1359 get_match_msg(Completions,Msg). % only succeeds if length of Completions > 0
1360
1361 % either keep full identifier or split off leading machine prefixes
1362 decompose_codes_id(IDCodes,IDCodes). % search for full identifier
1363 decompose_codes_id(IDCodes,ResIDCodes) :- append(_MachName,[0'. | Suffix], IDCodes),
1364 !, % peel of leading machine name; sometimes the machine name has changed and the id still exists
1365 Suffix = [_|_], % at least one character
1366 decompose_codes_id(Suffix,ResIDCodes).
1367
1368
1369