1:- module(pac_word,[let_w/2, let_wd/2, let_wl/2, let_wld/2,
    2	adjacent_interval/3, am_finals/2,
    3	expand_recognize_act/7,
    4	expand_w/5, expand_w/7, expand_wl/5, expand_wl/7,
    5	regex_am/2, regex_coalgebra/2, regex_compare/3,
    6	word/3, x_char_boole_form/2
    7				   ]).    8
    9:- use_module(pac('parse-regex')).   10:- use_module(pac('interval-boole')).   11:- use_module(pac('anti-subst')).   12:- use_module(pac(reduce)).   13:- use_module(pac('expand-pac')).   14:- use_module(pac(op)).
 word_am(X:regex, Y:automata) is det
True if X is converted to Y.
   20%
   21% ?- coalgebra:show_am("a").
   22% ?- coalgebra:show_am(".*").
   23% ?- coalgebra:show_am(@($)).
   24% ?- coalgebra:show_am(a).
   25% ?- coalgebra:show_am(a^(3-5)).
   26% ?- coalgebra:show_am(a^(>=(5))).
   27% ?- regex_coalgebra(a^(>=(1)), X).
   28% ?- regex_am(a^(>=(1)), X).
   29
   30word_am(char(X),A1)	:-!, word_am(char_boole_form(X),A2),
   31	word_am(i_boole(A2),A3),
   32	am_char(A3,A1).
   33word_am('I'(X),A1)	:-!, am_char_simple(X,A1).
   34word_am([],A1)		:-!,am_unit(A1).
   35word_am(coa(A,B),coa(A,B)):-!.
   36word_am(X+Y,A1)		:-!, word_am(X,A2),
   37	word_am(Y,A3),
   38	am_concat(A2,A3,A1).
   39word_am((X|Y),A1)	:-!, word_am(X,A2),
   40	word_am(Y,A3),
   41	am_cup(A2,A3,A1).
   42word_am((X\Y),A1)	:-!, word_am(X,A2),
   43	word_am(Y,A3),
   44	am_minus(A2,A3,A1).
   45word_am(X&Y,A1)		:-!, word_am(X,A2),
   46	word_am(Y,A3),
   47	am_cap(A2,A3,A1).
   48word_am(+X,A1)		:-!, word_am(X,A),
   49	word_am(A+ *(A),A1).
   50word_am(*(X),A1)		:-!, word_am(X,A2), am_star(A2,A1).
   51word_am(\+ _,A1)	:-!, word_am_aux(A1).
   52word_am(\ _,A1)		:-!, word_am_aux(A1).
   53word_am(?(X),A1):-!, word_am(([]|X),A1).
   54word_am(E^ >=(N),A1):-!, word_am(E,E0),
   55	word_am(E0^N,A2),
   56	word_am(*E0,A3),
   57	word_am(A2+A3,A1).
   58word_am(E^(I-J),A1)	:-K is J-I, !,
   59	word_am(E,E0),
   60	word_am(E0^I,A2),
   61	word_am(E0^ =<(K),A3),
   62	word_am(A2+A3,A1).
   63word_am(E^ =<(N),A1):-!, word_am(E,A2),
   64	am_power_lower(N,A2,A1).
   65word_am(E^N,A1)		:-!, word_am(E,A2), am_power(N,A2,A1).
   66word_am(rev(E),A1)	:-!, word_am(E,A2),
   67	am_reverse(A2,A1).
   68word_am(special(X,Is),A1):-!, am_special(X,Is,A1).
   69
   70%
   71word_am_aux(*('.'), _).
   72
   73			/****************************
   74			*     Special characters    *
   75			****************************/
   76
   77%
   78regex_macro($,	special($)).
   79regex_macro(comment,	"/\\*.*\\*/").
   80regex_macro(paragraph,	".*$$$*").
   81
   82%
   83final_special_pred(at_end_of_tape).
   84
   85%
   86special_char_class($, '\n').
   87
   88% ?- x_char_boole_form($, X), iboole:i_boole(X, I).
   89x_char_boole_form(X, I):- special_char_class(X, X0),
   90	once(char_boole_form(X0, I)).
   91
   92% So far, only "at_end_of_tape" is an example of special tokens.
   93% ?- am_special($, [1,2,3], E).
   94
   95am_special($, Interval_list,  coa(E, 1)):-
   96	sort(Interval_list, Interval_list0),
   97	E0 = [1- [ special(at_end_of_tape),
   98		   Interval_list0 - 2	],
   99		   2 - [[]]],
  100	split_goto(E0, E).
  101
  102%
  103compile_special_char($, Ints, N, I, J, M,
  104		     [R|P], P) :-
  105	(	N ==0,
  106		Head0 =.. [I, [V |X], Y] ,
  107		CallJ =.. [J, X, Y]
  108	;       N ==2,
  109		Head0 =.. [I, A, B, [V |X], Y],
  110		CallJ =.. [J, A, B, X, Y]
  111	),
  112	( Ints = (U-U) -> (U = V, V_test_code=true)
  113	;   once(generate_code_test(Ints, V, V_test_code))),
  114	slim_goal((V_test_code, CallJ), Body0),
  115	prefix_convention(M, Head0:-Body0, R).
  116%
  117compile_special_pred(at_end_of_tape, [I, _, N, M], Head:-true):-
  118	(	N ==0, 	Head0 =..[I, [],[]]
  119	;       N ==2,  Head0 =..[I, A, A, [],[]]
  120	),
  121	prefix_convention(M, Head0, Head).
  122
  123
  124% ?-  phrase(w(char(alnum) + *(char(alpha))), `a1bc`, S).
  125% ?-  phrase(w(ab+cd), `abcde`, S).
  126% ?-  phrase(w("abcd"), `abcde`, S).
  127% ?-  phrase(w(i(2)+i(3)), [2,3], S).
  128% ?-  regex_coalgebra("23", S).
  129% ?-  regex_coalgebra(i(2)+i(3), S).
  130
  131% ?-  phrase(w(i(2)+i(3)), [2,3], S).
  132% ?-  phrase(w(i(2)^(=<(3))), [2,2], S).
  133% ?-  phrase(w(i(2)^(>=(3))), [2,2,2,2], S).
  134
  135% ?- let_w(X, ".*"), phrase(X, `abc`, R).
  136% ?- let_wd(X, ".*"), call(X, A, [], `abc`, R).
  137% ?- let_wl(X, ".*"), phrase(X, `abc`, R).
  138% ?- let_wld(X, ".*"), call(X, A, [], `abc`, R).
  139
  140let_w(F, X) :- once(let_expand_regex(w, 0, X, user, F)).
  141let_wd(F, X):- once(let_expand_regex(w, 2, X, user, F)).
  142let_wl(F, X):- once(let_expand_regex(wl, 0, X, user, F)).
  143let_wld(F, X):- once(let_expand_regex(wl, 2, X, user, F)).
  144
  145%
  146let_expand_regex(W, N, Regex, M_prefix, Pred):-
  147	regex_coalgebra_code(Regex, coa(C, I, _)),
  148	(	W == wl -> null_last_coa(C, C0); C0=C),
  149	expand_coa(N, C0, I, M_prefix, Pred, P, []),
  150	maplist(assert, P).
  151
  152% ?- let_sed(X,  w("a") >> =([])).
  153% ?- regex_word("a", _4774, _4776).
  154% ?- let_sed(X,  w("a") >> =([])), call(X, `abac`, S), basic:smash(S, S0).
  155% ?- let_sed(X,  w("a") >> =([])), call(X, `abac`, S), basic:smash(S).
  156% ?- let_sed(X,  w("a") >> =([])), call(X, `abac`, S), basic:smash(S).
  157% ?- let_sed(X,  w("a") >> =([])), call(X, `abac`, S), basic:smash(S).
  158% ?- let_sed(X,  (w("a", A), w("b", B)) >> append(B, A)), call(X, `abab`, S), basic:smash(S).
  159% ?- let_sed(X,  s/"a"/"x"), call(X, `abac`, S), basic:smash(S).
  160% ?- let_sed(X,  b/"a"/"x"), call(X, `abac`, S), basic:smash(S).
  161% ?- let_sed(X,  a/"a"/"x"), call(X, `abac`, S), basic:smash(S).
  162% ?- let_sed(X,  d/"a"), call(X, `abac`, S), basic:smash(S).
  163% ?- let_sed(X,  w/"a"/"xxx"/"yyy"), call(X, `abac`, S), basic:smash(S).
  164% ?- let_sed(F,  wl("a+", A) >> pred(A, ([B]:- length(A, L), length(B,L), maplist(=(0'b), B)))), call(F, `aaa`, R), basic:smash(R).
  165% ?- let_sed(F,  (w(".*", A), wl("b+")) >> pred(A, [A])),  call(F, `aaabbccc`, R), basic:smash(R).
  166% ?- basic:herbrand(_, `(w(".*", A), wl("b+")) >> pred(A, [A])`, H), let_sed(F, H),  call(F, `aaabbccc`, R), basic:smash(R).
  167
  168user:let_sed(X, Y) :- prolog_load_context(module, M),
  169	once(let_sed(X, M, Y)).
  170
  171%
  172let_sed(X, M, S) :- pac:expand_sed(S, [F, W, A]),
  173	once(expand_recognize_act(F, W, A, M, X, P, [])),
  174	maplist(assert, P).
  175
  176% ?- regex_coalgebra("[^\\./]*", X).
  177% ?- regex_coalgebra(( "\"([^\"\\\\]|(\\\\.))*\"" | "'([^'\\\\]|(\\\\.))*'" | "[^ \t\"']+"), X).
  178% ?- regex_coalgebra(*(a|b)+ [a]+(*([]))+ (*(*([]|[]))), N).
  179% ?- regex_coalgebra(*(a|b)+ "a"+(*([]))+ (*(*([]|[]))), N).
  180% ?- regex_coalgebra(*(.), X).
  181% ?- regex_coalgebra(".*", X).
  182% ?- regex_coalgebra(ab+cd, X).
  183% ?- regex_coalgebra(ab+cd, X, [code]).
  184
  185% ?- regex_coalgebra_code("a*", X).
  186% ?- regex_coalgebra_code(ab+cd, X).
  187% ?- regex_coalgebra_char(".*", X).
  188% ?- regex_coalgebra_char("a*", X).
  189% ?- regex_coalgebra_char("[adlz]", X).
  190% ?- regex_coalgebra_char(ab+cd, X).
  191% ?- regex_coalgebra_char(a, X).
  192% ?- regex_coalgebra_char(i([-1, -1]), X).
  193% ?- regex_coalgebra_char("a", X).
  194
  195regex_coalgebra(X, coa(E0, I, Fs), Options):- once(regex_am(X,  coa(E, I))),
  196	am_finals(coa(E, _), Fs),
  197	(  memberchk(char, Options)
  198	->	map_coa_char_int(E, E0)
  199	;	E0 = E
  200	).
  201
  202%
  203regex_coalgebra(X, C):- regex_coalgebra(X, C, [code]).
  204%
  205regex_coalgebra_code(X, C):- regex_coalgebra(X, C, [code]).
  206%
  207regex_coalgebra_char(X, C):- regex_coalgebra(X, C, [char]).
  208
  209		/***************************************
  210		*     State Transition by Automaton    *
  211		***************************************/
  212
  213% ?- regex_coalgebra_char("a*", X).
  214% ?- regex_coalgebra_char("a", X).
  215% ?- map_coa_char_int([1-[[97-97]-2], 2-[[]]], _508).
  216% ?- regex_coalgebra_char("a*", X), state_move([a], 1, S, X).
  217% ?- (regex_coalgebra_char("a*", X), state_move([a,a,a], 1, S, X)).
  218% ?- (regex_coalgebra("a*", X, [char]), state_move([a,a], 1, S, X)).
  219% ?- regex_coalgebra("\001\*", X, [code]).
  220% ?- regex_coalgebra(i([-1, -1]), X).
  221
  222state_move([], S, S, _).
  223state_move([X|R], S, S0, Coa):-
  224	once(state_move_one(X, S, S1, Coa)),
  225	state_move(R, S1, S0, Coa).
  226%
  227state_move_one(X, S, S1, coa(E,_,_)):- memberchk(S-Dots, E),
  228	member(Intervals-S1, Dots),
  229	member(A-B, Intervals),
  230	greater_or_eq(X, A),
  231	smaller_or_eq(X, B).
  232%
  233greater_or_eq(_, inf).
  234greater_or_eq(X, I):- X @>= I.
  235%
  236smaller_or_eq(_, sup).
  237smaller_or_eq(X, I):- X @=< I.
  238
  239			/***************************
  240			*   map character classes  *
  241			***************************/
  242% ?-  phrase(w(char(alnum) + *(char(alpha))), `a1bc`, S).
  243% ?-  phrase(w(ab+cd), `abcde`, S).
  244% ?-  phrase(w("abcd"), `abcde`, S).
  245
  246% ?-  map_coa_char_int(R, [1-[[a-a]-2], 2-[[]]]).
  247% ?-  map_coa_char_int(R, [1-[[a-a]-2], 2-[[]]]), map_coa_char_int(R, S).
  248
  249map_coa_char_int(X, Y):-
  250	maplist(coa_char_int_aux, X, Y).
  251%
  252coa_char_int_aux(I-R, I-R0):-  maplist(map_goto_char_int, R, R0).
  253
  254%
  255map_goto_char_int([], []).
  256map_goto_char_int(Is-S, Js-S):- maplist(goto_char_int_aux, Is, Js).
  257%
  258goto_char_int_aux(A-B, A0-B0):- char_int(A, A0), char_int(B, B0).
  259
  260%
  261char_int(inf, inf).
  262char_int(sup, sup).
  263char_int(X, Y):-
  264	(	(	is_of_type(negative_integer, X)
  265		;	is_of_type(negative_integer, Y)
  266		)
  267	->	X = Y
  268	;	char_code(Y, X)
  269	).
  270
  271			/*********************
  272			*     goto states    *
  273			*********************/
  274
  275%  ?-  am_char_dict([2-[[inf-sup]-3]], C, [], P).
  276%@ C = [2-[_G2137-3]],
  277%@ P = [[inf-sup]-_G2137].
  278
  279am_char_dict([], [], P, P).
  280am_char_dict([[]|Z], [[]|Z0], P, Q):- am_char_dict(Z, Z0, P, Q).
  281am_char_dict([X-Y|Z], [X-Y0|Z0], P, Q):-
  282	once(goto_dict(Y, Y0, P, R)),
  283	am_char_dict(Z, Z0, R, Q).
  284
  285%
  286goto_dict([], [], P, P).
  287goto_dict([[]|X],[[]|Y], P, Q):- goto_dict(X, Y, P, Q).
  288goto_dict([I-S|X],[V-S|Y], P, Q):- add_char_dict(I, P, P0, V),
  289	goto_dict(X, Y, P0, Q).
  290
  291%
  292add_char_dict(I, P, P, V):- memberchk(I-V, P).
  293add_char_dict(I, P, [I-V|P], V).
  294
  295%
  296expand_char_class(U, V):- maplist(expand_char_class_aux, U, V).
  297
  298%
  299expand_char_class_aux(X-Y, X-Y0):-
  300	maplist(expand_char_class_aux_aux, Y, Y0).
  301%
  302expand_char_class_aux_aux([], []):- !.
  303expand_char_class_aux_aux(V-S, Gotos) :-
  304	maplist(expand_char_class_aux_aux_aux(S), V, Gotos).
  305%
  306expand_char_class_aux_aux_aux(S, A, A-S).
  307
  308% ?- split_goto([1-[[], [1,2,3]-s, [2,3]-t], 1-[[1,2,3]-s, [2,3]-t]], X).
  309split_goto(X, Y):-	maplist(split_goto_aux, X, Y).
  310
  311%
  312split_goto_aux(I-S, I-S0):- distribute_state(S, S0, []).
  313
  314%
  315distribute_state(X, Y):- distribute_state(X, Y, []).
  316
  317%
  318distribute_state([X-S|Y], Z, U):- distribute_state(X, S, Z, V),
  319	distribute_state(Y, V, U).
  320distribute_state([A|X], [A|Y], Z):- distribute_state(X, Y, Z).
  321distribute_state([], X, X).
  322
  323%
  324distribute_state([A|R], S, [A-S|P], Q):- distribute_state(R, S, P, Q).
  325distribute_state([], _, Z, Z).
  326
  327			/*****************************
  328			*     automaton synthesis    *
  329			*****************************/
  330
  331%
  332merge([X,X|Y], U):- merge([X|Y], U).
  333merge([X|R], [X|U]):- merge(R, U).
  334merge([], []).
  335
  336% ?- regex_am((.), R).
  337% ?- regex_am(($), R).
  338% ?- regex_am("abc", R).
  339
  340regex_am(X, Y):- regex_word(X, X0, Basic_interval_dict),
  341 	word_am(X0, Y0),
  342 	am_connected_region(Y0, Y0_reachable),
  343 	am_remove_empty_states(Y0_reachable, Y0_slim),
  344	once(am_remove_useless_states(Y0_slim, Y0_useful)),
  345 	once(am_char_back(Y0_useful, Basic_interval_dict, Y1)),
  346 	am_normal(Y1, Y).
  347
  348%
  349word_normal_am --> word_am,
  350	am_connected_region,
  351	am_remove_empty_states,
  352	am_remove_useless_states,
  353	am_normal.
  354%
  355regex_word(X, Y):- regex_word(X, Y, _).
 regex_word(+E:regex, -W:word, -D:intval_dict) is det
True if E is conveted to W with D.

Simplest usage:

?- pac_word:regex_word(("."), Y, Z).
Y = 'I'([1]),
Z = [inf-sup-1] .
?- regex_word(char(alpha), Y, Z).
Y = 'I'([1, 2]),
Z = [65-90-1, 97-122-2] .
?- regex_word(special($), Y, Z).
Y = special($, [x($, 1)]),
Z = [x($, 10-10)-x(1)] .
  373x_snd(x(_, I), I):-!.
  374x_snd(I, I).
  375
  376% ?- regex_word((special($) + a), Y, Z).
  377regex_word(X, Y, Basic_interval_dict):-
  378	once(parse_interval(X, Y, P, [])),
  379	sort(P, SortedP),
  380	once(merge(SortedP, PX)),
  381	zip_hyphen(A, Target_interval_list, PX),
  382	maplist(x_snd, A,  A0),
  383	zip_hyphen(A0, Refinement, Pzip),
  384	refine_char_dict(Pzip),
  385	basic_interval_index(Refinement,
  386	     Partition_in_index,
  387	     Basic_interval_dict0),
  388	zip_hyphen(A, Partition_in_index, Char_dict),
  389	mark_basic_interval_dict(Basic_interval_dict0,
  390		 Char_dict,
  391		 Basic_interval_dict),
  392	mark_interval_block_list(Char_dict,
  393		 Partition_in_index,
  394		 Target_interval_list).
  395
  396% [2014/09/02]
  397refine_char_dict(Tzip):-  zip_hyphen(Left, Right, Tzip),
  398	iboole:m_partition(Left, Right).
 mark_basic_interval_dict(+X:zip, +P:zip, -Y:zip) is det
True if Y is unified with a basic interval dict built from X and Y.

sample use: ?- mark_basic_interval_dict([(a-b)-1, (c-d)-2, (e-f)-3], [x($, _)-[1], x(#, _)-[2], [_]-[3,4]], Y). Y = [x($, a-b)-x(1), x(#, c-d)-x(2), e-f-3] .

  409mark_basic_interval_dict(X, P, Y):-
  410	maplist(mark_basic_interval_dict_aux(P), X, Y).
  411
  412%
  413mark_basic_interval_dict_aux(P, A-N, x(S, A)- x(N)):-
  414				member(x(S,_)-L, P),
  415				memberchk(N, L).
  416mark_basic_interval_dict_aux(_, U, U).
  417
  418%
  419mark_interval_block_list(Assoc, IB, IBX):-
  420	maplist(mark_interval_block(Assoc), IB, IBX).
  421
  422%
  423mark_interval_block(Assoc, L, LX):-
  424	maplist(mark_interval(Assoc), L, LX).
  425
  426%
  427mark_interval(Assoc, I, x(S,I)):- member(x(S, _)-W, Assoc),
  428	memberchk(I, W).
  429mark_interval(_, I, I).
  430
  431%
  432am_char_back(coa(X, I), M, coa(Y, I)):-	maplist(am_char_back_aux(M), X, Y).
  433
  434%
  435am_char_back_aux(M, I-A, I-B):- maplist(am_char_back_aux_aux(M), A, B).
  436
  437%
  438am_char_back_aux_aux(M, x(_X, K)-J, A-J) :-  memberchk(A-x(K), M).
  439am_char_back_aux_aux(M, C-J, D-J) :-  memberchk(D-C, M).
  440am_char_back_aux_aux(_, U, U).
  441
  442%
  443basic_interval_index(Ks, Js, Basic_interval_dict):-
  444	maplist(zip_hyphen, Ks, Js,  U),
  445	flatten(U, V),
  446	sort(V, Basic_interval_dict0),
  447	once(merge(Basic_interval_dict0, Basic_interval_dict)),
  448	length(Basic_interval_dict, N),
  449	(	N==0
  450	->	true
  451	; 	numlist(1, N, NZip),
  452		zip_hyphen(_, NZip, Basic_interval_dict)
  453	).
  454
  455
  456			/************************
  457			*     parse interval    *
  458			************************/
 parse_interval(+X:word, -Y:word, -I:intervals, -I0:intervals) is det
True if Y is unified with X such that all intervals in X are extracted into I (minus I0), so that Y and X are equivalent after refinement of the intervals I (minus I0).

Simple usage: ?- parse_interval("[a-z]", R, X, []). R = 'I'(_G5557), X = [[97-122]-_G5557] .

  471% ?-  phrase(w(i([-1, -1])), [-1], X).
  472% ?-  expand_phrase(w(i([-1, -1])), [], G, L, []).
  473
  474% ?- regex_coalgebra("abc*", X, [code]).
  475% ?- (regex_coalgebra("(\000\|\001\)*", X, [code]), state_move([0,1,0,0], 1, S, X)).
  476% ?- regex_coalgebra(i(-1), X,  [code]).
  477% ?- regex_coalgebra(i([-1, -2]), X,  [code]).
  478% ?- (regex_coalgebra(*(i([-5 - -1])), X, [code]), state_move([-1, -2, -3], 1, S, X)).
  479% ?- (regex_coalgebra(i(-1) + *(i(0)) + i(-2), X, [code]), state_move([-1, -2], 1, S, X)).
  480% ?- (regex_coalgebra(i(-1) + *(i(0)) + i(-2), X, [code]), state_move([-1, 0,0, 0, 0, -2], 1, S, X)).
  481% ?- show_phrase(w("a*$")).
  482% ?- coalgebra:show_am("abc*").
  483%@ true.
  484
  485
  486parse_interval(X, Y) --> i_parse(X, Y).
  487
  488%
  489i_parse((.), 'I'(U))	--> [[inf-sup]-U].
  490i_parse(char(X), 'I'(U))	--> [I-U],
  491	{ once(char_boole_form(X, X0)),  i_boole(X0, I) }.
  492i_parse(i(X), 'I'(U)) --> [I - U],
  493	{ once(i_normal_class_form(X, Y)),  i_boole(Y, I) }.
  494i_parse('C'(X), U)	--> i_parse_codes(X, U).
  495i_parse([], [])		--> [].
  496i_parse(special(X),  special(X, U)) --> [x(X, I)-U],
  497 	{ x_char_boole_form(X, X0),  i_boole(X0, I) }.
  498i_parse(out(X), U)	-->  i_parse(char(out(X)), U).
  499i_parse(dot(X), U)	-->  i_parse(char(X), U).
  500i_parse(X+Y, U+V)	-->  i_parse(X, U), i_parse(Y, V).
  501i_parse(X|Y, U|V)	-->  i_parse(X, U), i_parse(Y, V).
  502i_parse(X\Y, U\V)	-->  i_parse(X, U), i_parse(Y, V).
  503i_parse(X&Y, U&V)	-->  i_parse(X, U), i_parse(Y, V).
  504i_parse(+(X), +(U))	-->  i_parse(X, U).
  505i_parse(*(X), *(U))	-->  i_parse(X, U).
  506i_parse(\+(X), U)	-->  i_parse( *(.) \ X, U).
  507i_parse(\(X), U)	-->  i_parse( *(.) \ X, U).
  508i_parse(rev(X), rev(U))	-->  i_parse(X, U).
  509i_parse(?(X), ?(U))	-->  i_parse(X, U).
  510i_parse(E^N, E0^N)	-->  i_parse(E, E0).
  511i_parse(regexlist(L), regexlist(L0))   -->  i_parse_list(L, L0).
  512i_parse(@(X), U)	--> {regex_macro(X, Y)}, i_parse(Y, U).
  513i_parse("", [])		--> [].
  514i_parse(X, U)		--> {string(X)},
  515 	{parse_regex(X, Y)},
  516	i_parse(Y, U).
  517i_parse(X, U)		--> {atom(X)},  {atom_codes(X, Y)}, i_parse_codes(Y, U).
  518i_parse(X, U)		--> {number(X)}, {number_codes(X, Y)}, i_parse_codes(Y, U).
  519i_parse(X, _)		--> {throw(i_parse:'unknown hybrid regex found'(X))}.
  520
  521%
  522i_parse_list([E|Es], [F|Fs]) --> i_parse(E, F),
  523	i_parse_list(Es, Fs).
  524i_parse_list([], [])	-->  [].
  525
  526%
  527i_parse_codes([X], 'I'(U))  --> [[X-X] - U].
  528i_parse_codes([X, Y|Z], 'I'(U) + R) --> [[X-X]- U],
  529	i_parse_codes([Y|Z], R).
  530i_parse_codes([], [])  --> [].
  531
  532% Note.
  533% ?- eval(:(=) @ (:(=) @ (:(=) @ 1)), V).
  534
  535% ?- am_linear([a,b], X).
  536% ?- am_linear([], X).
  537
  538am_linear(Cs, coa(E, 1)):- once(am_linear(Cs, 1, E, [])).
  539
  540am_linear([], N, [N-[[]]|L], L).
  541am_linear([A|R], N, [N-[A-N0]|L], L0):- N0 is N+1,
  542 	am_linear(R, N0, L, L0).
 char_boole_form(+F:char_exp, -F0:char_exp) is det
True if F is converted to F0 such that all boolean expressions on intevals are evaluated.

A simple usage: ?- char_boole_form(a|b, X). X = ([97-97];[] | [98-98];[]).

  553char_boole_form((.), [inf-sup]).
  554char_boole_form([], []).
  555char_boole_form(X-Y, [A0-A1]):-
  556	(atom(X), atom_length(X, 1); integer(X)),
  557	(atom(Y), atom_length(Y, 1); integer(Y)),
  558	( atom(X) -> char_code(X, X0); X0=X ),
  559	( atom(Y) -> char_code(Y, Y0); Y0=Y ),
  560	msort([X0,Y0], [A0,A1]).
  561char_boole_form(X, Y):- atom(X), reserved_char_class(Assoc),
  562	memberchk(X-C, Assoc),
  563	maplist(char_boole_form_aux, C, C0),
  564	char_boole_form(C0, Y).
  565char_boole_form(X, Y):- atom(X), atom_codes(X, Y0),
  566	char_boole_form(Y0, Y).
  567char_boole_form(X, [X-X]):- integer(X).
  568char_boole_form([X|Y], X0;Y0):- char_boole_form(X, X0),
  569	char_boole_form(Y, Y0).
  570char_boole_form(dot(X), Y):- char_boole_form(X, Y).
  571char_boole_form(out(X), out(Y)):- char_boole_form(X, Y).
  572char_boole_form(^(X), Y):- char_boole_form(out(X), Y).
  573char_boole_form(X^N, Y^N):- char_boole_form(X, Y).
  574char_boole_form(\+(X), Y):- char_boole_form(out(X), Y).
  575char_boole_form(\(X), Y):- char_boole_form(out(X), Y).
  576char_boole_form(X|Y, X0|Y0):- char_boole_form(X, X0),
  577	char_boole_form(Y, Y0).
  578char_boole_form(X;Y, Z):- char_boole_form(X|Y, Z).
  579char_boole_form(\(X,Y), \(X0,Y0)):- char_boole_form(X, X0),
  580	char_boole_form(Y, Y0).
  581char_boole_form(X&Y, X0&Y0):- char_boole_form(X, X0),
  582	char_boole_form(Y, Y0).
  583
  584%
  585char_boole_form_aux(A-B, A0-B0):-  char_code(A, A0), char_code(B, B0).
  586char_boole_form_aux(A, A0):- char_code(A, A0).
  587
  588
  589% ?- i_normal_class_form([-1, -2],  X).
  590%@ X = ([-1- -1];[-2- -2];[]) .
  591
  592i_normal_class_form([], []).
  593i_normal_class_form(X, [X-X]):- integer(X).
  594i_normal_class_form([X-Y|Z], ([X-Y]; U)):- i_normal_class_form(Z, U).
  595i_normal_class_form([X|Z], ([X-X]; U)):- i_normal_class_form(Z, U).
  596
  597%%% Tiny helpers
  598zip_hyphen([], [], []).
  599zip_hyphen([A|B], [C|D], [A-C|R]):- zip_hyphen(B, D, R).
  600
  601%
  602zip_comma([], [], []).
  603zip_comma([A|B], [C|D], [(A,C)|R]):- zip_comma(B, D, R).
  604
  605%
  606byte_in_bits(N, Bits):-  poly:bits(N, [], Bits0),
  607	length(Bits, 8),
  608	append(P, Bits0, Bits),
  609	maplist(=(0), P).
  610
  611
  612			/******************************************
  613			*     automaton sysnthesis basic steps    *
  614			******************************************/
 am_determine(+C:coa, -D:coa) is det
True if D is unified with a deterministic version of C.
  621am_determine(coa(E, I), D):- am_determine(E, I, E0, I0),
  622	am_fresh(coa(E0, I0), D0),
  623	am_clean(D0, D).
  624
  625am_determine(E, I, D, [I]):-  once(am_determine([[I]], [], E, D, [])).
  626
  627am_determine([], _, _, P, P).
  628am_determine([S|R], H, E, P, Q):-  memberchk(S, H),
  629	am_determine(R, H, E, P, Q).
  630am_determine([S|R], H, E, [S-C|P], Q):-
  631	expand_power_state(S, E, C, R0, R),
  632	am_determine(R0, [S|H], E, P, Q).
 am_slim(+C:coa, -D:coa) is det
True if D is unified with a slimmed version of C.
  638am_slim(coa(E, I), coa(D, I)):- once(am_slim([I], [], E, D, [])).
  639
  640am_slim([], _, _, P, P).
  641am_slim([S|R], H, E, P, Q):-  memberchk(S, H),
  642	am_slim(R, H, E, P, Q).
  643am_slim([I|A], H, E, [I-U|P], Q):- once(select(I-U, E, E0)),
  644	once(am_slim(U, A, [I|H], E0, P, Q)).
  645
  646%
  647am_slim([], A, H, E, P, Q):- am_slim(A, H, E, P, Q).
  648am_slim([_-G|R], A, H, E, P, Q):- am_slim(R, [G|A], H, E, P, Q).
  649am_slim([_|R], A, H, E, P, Q):-  am_slim(R, A, H, E, P, Q).
  650
  651% ?- expand_power_state([x,y], [x-[a-2, b-3], y-[a-2, b-4, c-5]], R, A, []).
  652%@ R = [a-[2], b-[3, 4], c-[5]],
  653%@ A = [[2], [3, 4], [5]] .
  654% ?- expand_power_state([x,y], [x-[[], a-2, b-3], y-[a-2, b-4, c-5]], R, A, []).
  655%@ R = [[], a-[2], b-[3, 4], c-[5]],
  656%@ A = [[2], [3, 4], [5]] .
  657% ?- trace, expand_power_state([x,y], [x-[special(s), a-2, b-3], y-[a-2, b-4, c-5]], R, A, []).
  658
  659expand_power_state(S, E, Coa, P, Q):-
  660	foldl(expand_power_state_aux(E), S, [], Pairs0),
  661	sort(Pairs0, Pairs),
  662	once(merge_pairs(Pairs, Coa, [], P, Q)).
  663%
  664expand_power_state_aux(E, K, L, M):-  memberchk(K-B, E),
  665    foldl(cons, B, L, M).
  666
  667cons(X, Y, [X|Y]).
  668
  669% ?-is_deterministic(coa([1-[a-1, b-1]], _)).
  670% ?-is_deterministic(coa([1-[a-1, a-1]], _)).
  671is_deterministic(coa(E, _)):- is_deterministic(E).
  672
  673is_deterministic([_-A|R]):- \+ consecutive_same_key(A),
  674		is_deterministic(R).
  675is_deterministic([]).
  676
  677%
  678consecutive_same_key([A-_, A-_|_]).
  679consecutive_same_key([_, A|B]):- consecutive_same_key([A|B]).
  680
  681
  682			/*************************************
  683			*     automata state minimization    *
  684			*************************************/
 am_minimum(+C:coa, -D:coa) is det
True if D is unified with a state minimized version of C.
  690% ?-  regex_coalgebra(".*****",  X).
  691%@ X = coa([1-[[], dot([inf-sup])-1]], 1, [1]) .
  692% ?- am_minimum([2-[[], (inf-sup)-3], 3-[[], (inf-sup)-3]], 2, R).
  693%@ R = coa([1-[[], inf-sup-1]], 1) .
  694
  695% ?- am_minimum(coa([1-[a-2, b-1], 2-[a-1, b-2], 3-[a-3, b-1]],  1), D).
  696%@ D = coa([1-[a-1, b-1]], 1) .
  697
  698am_minimum(coa(E,I), C):- once(am_minimum(E, I, C)).
  699
  700am_minimum(E, I, coa(E3, J)):-  minimum_am_qmap(E, Qmap),
  701	(	Qmap == []
  702	->	E3 = E,
  703		J  = I
  704	; 	member(X-I0,  Qmap),
  705		memberchk(I, X),
  706		quotient_coa(E, Qmap, E1),
  707		am_clean(coa(E1, I0), coa(E2, J)),
  708		sort(E2, E3)
  709	).
  710
  711make_singleton(I, [I]).
  712%
  713minimum_am_qmap(Coa, Qmap):-
  714	once(am_conflict_pairs(Coa, Conflicts)),
  715	sort(Conflicts, CSorted),
  716	once(pairs_to_assoc(CSorted, Inicon, [])),
  717	all_states(Coa, All),
  718	assoc_product(All, All, Prod, []),
  719	once(assoc_subtract(Prod, Inicon, Rel)),
  720	maplist(make_singleton, All, Singletons),
  721	once(coa_union_find(Rel, Singletons, Clusters)),
  722	(	Clusters == []
  723	->	Qmap = []
  724	;	length(Clusters, N),
  725		numlist(1, N, S),
  726		zip_hyphen(Clusters, S, Qmap)
  727	).
  728
  729%
  730% quotient_coa(Eqs, Qmap, Eqs0) :-
  731% 	maplist(pred(Qmap, [S-L, S0-L0]:-
  732% 		(	member(Cluster-S0, Qmap),
  733% 			memberchk(S, Cluster),
  734% 			maplist(pred(Qmap,
  735% 					([A-G, A-G0]:-
  736% 						(member(GCluster-G0, Qmap),
  737% 						 memberchk(G, GCluster)))
  738% 					&  [X, X] ),
  739% 				    L, L1 ),
  740% 			predsort(compare_right, L1, L0)
  741% 		)), Eqs, Eqs0).
  742
  743%
  744quotient_coa(Eqs, Qmap, Eqs0) :- maplist(quotient_coa_aux(Qmap), Eqs, Eqs0).
  745
  746%
  747quotient_coa_aux(Qmap, S-L, S0-L0) :-
  748			member(Cluster-S0, Qmap),
  749			memberchk(S, Cluster),
  750			maplist(quotient_coa_aux_aux(Qmap), L, L1),
  751			predsort(compare_right, L1, L0).
  752
  753%
  754quotient_coa_aux_aux(Qmap, A-G, A-G0) :-
  755	member(GCluster-G0, Qmap),
  756	memberchk(G, GCluster).
  757quotient_coa_aux_aux(_, X, X).
  758
  759%
  760am_normal(coa([], _), C):- am_empty(C).
  761am_normal(coa(A,I), coa(B, I)):-  sort(A, C), am_normal(C, B, []).
  762
  763%
  764am_normal([], P, P).
  765am_normal([I-A|R], [I-B|P], Q):-
  766	am_normal(I, R, R0, As, []),
  767	append([A|As], H),
  768	sort(H, G),
  769	am_normal_body(G, B),
  770	am_normal(R0,  P,  Q).
  771
  772am_normal_body([], []).
  773am_normal_body([[]|G], [[]|B]) :- am_normal_body(G, B).
  774am_normal_body([special(X)|G], [special(X)|B]) :- am_normal_body(G, B).
  775am_normal_body(G, B) :-  keysort_right(G, G0),
  776	join_char(G0, B0),
  777	maplist(am_normal_body_aux, B0, B).
  778
  779%
  780am_normal_body_aux(I-X, J-X):- x_normal(I, J).
  781
  782%
  783am_normal(I, [I-A|R], R0, [A|P], Q):- am_normal(I, R, R0, P, Q).
  784am_normal(_, R, R, P, P).
  785
  786%
  787compare_right(C, X-Z, Y-Z):- compare(C, X, Y).
  788compare_right(C, _-X, _-Y):- compare(C, X, Y).
  789compare_right(=, X, X).
  790compare_right(<, _, _-_).
  791compare_right(>, _-_, _).
  792compare_right(>, _, _).
  793
  794% ?- x_compare(C, x(2), 1-2).
  795x_compare(C,  x(X), x(Y)):- compare(C, X, Y).
  796x_compare(<,  x(_), _-_).
  797x_compare(>,  _-_, x(_)).
  798x_compare(C,  A, B):- iboole:i_compare(C, A, B).
  799
  800%
  801x_normal(X, Y):- x_separate(X, X0, R),
  802	iboole:i_normal(R, R0),
  803	append(X0, R0, Y).
  804
  805x_separate([], [], []).
  806x_separate([A-B|R], U, [A-B|V]):-  x_separate(R, U, V).
  807x_separate([X|R], [X|U], V):- x_separate(R, U, V).
  808
  809
  810% ?- merge_pairs([a-2, a-3, a-2,  b-1, b-3, c-2], R, [], S, []).
  811%@ R = [a-[2, 3], b-[1, 3], c-[2]],
  812%@ S = [[2, 3], [1, 3], [2]].
  813
  814merge_pairs([I-X|Cs], [I-Pow|D0], D, [Pow|A0], A):-
  815	power_state(I, Cs, Cs0, Pow0, []),
  816	sort([X|Pow0], Pow),
  817	merge_pairs(Cs0, D0, D, A0, A).
  818merge_pairs([X|Cs], [X|D0], D, A0, A):-
  819	merge_pairs(Cs, D0, D, A0, A).
  820merge_pairs([], D, D, A, A).
  821
  822%
  823power_state(I, [I-G|R], R0, [G|P], Q):-
  824	power_state(I, R, R0, P, Q).
  825power_state(_, A, A, B, B).
  826
  827% ?- join_char_interval([], []).
  828% ?- join_char_interval([(3-4)-t], R).
  829%@ R = [[3-4]-t] .
  830% ?- coa:join_char_interval([(inf-4)-t, (5-sup)-t], R).
  831%@ R = [[inf-4, 5-sup]-t].
  832% ?- join_char_interval([(10-sup)-t, (20-20)-s, (inf-4)-t], R).
  833%@ R = [[20-20]-s, [10-sup, inf-4]-t].
  834
  835keysort_right(X,Y):- predsort(keysort_right_aux, X, Y).
  836%
  837keysort_right_aux(=, [], []).
  838keysort_right_aux(<, [], _).
  839keysort_right_aux(>, _, []).
  840keysort_right_aux(C, _-U, _-V):- U @> V, C=(>); C=(<).
  841
  842%
  843join_char_interval(A, B):- keysort_right(A, A0), join_char(A0, B).
  844
  845%
  846join_char([], []).
  847join_char([[]|R], [[]|S]):- join_char(R, S).
  848join_char([X-A|R], [[X|Xs]-A|S]):-
  849	once(join_char(A, R, Xs, R0)),
  850	join_char(R0, S).
  851
  852%
  853join_char(_, [], [], []).
  854join_char(A, [X-A|R], [X|Xs], S):-
  855	join_char(A, R, Xs, S).
  856join_char(_, R, [], R).
  857
  858% ?- merge_target([a-1], R, []).
  859%@ R = [a-[1]].
  860% ?- merge_target([a-1, a-2], R, []).
  861%@ R = [a-[1, 2]] .
  862% ?- merge_target([a-1, a-2, b-3], R, []).
  863%@ R = [a-[1, 2], b-[3]] .
  864% ?- merge_target([[], a-1, a-2, b-3], R, []).
  865%@ R = [[], a-[1, 2], b-[3]] .
  866% ?- merge_target([[], a-1,  b-3, a-2], R).
  867%@ R = [[], a-[1, 2], b-[3]] .
  868
  869merge_target(X, Y):- sort(X, X0), once(merge_target(X0, Y, [])).
  870
  871merge_target([], P, P).
  872merge_target([[]|R], [[]|P], Q):- merge_target(R, P, Q).
  873merge_target([I-X|R], [I-Xs|P], Q):-
  874	merge_target(I, R, R0, [X], Xs),
  875	merge_target(R0, P, Q).
  876
  877%
  878merge_target(I, [I-X|R], R0, P, Q):- contract_insert(X, P, P0),
  879	merge_target(I, R, R0, P0, Q).
  880merge_target(_, R, R, P, P).
  881
  882
  883			/********************
  884			*     union-find    *
  885			********************/
  886% ?- coa_union_find([a-b,x-y, x-x, y-z, b-c], [], R).
  887% ?- coa_union_find([a-b,x-y, x-x, y-z, b-c], [], R).
  888
  889coa_union_find([], X, X).
  890coa_union_find([X-Ys|R],C,D):-coa_union_find(Ys, X, C,C1),
  891	coa_union_find(R,C1,D).
  892
  893coa_union_find([], _, P, P).
  894coa_union_find([Y|Ys], X, P, Q):- once(coa_union_find_one(X, Y, P, P0)),
  895	coa_union_find(Ys, X, P0, Q).
  896
  897coa_union_find_one(X,Y,Z,U):-find_cluster(X,Z,C,Z0),
  898	(memberchk(Y, C) -> U=[C|Z0]
  899	; find_cluster(Y, Z0, C0, Z1),
  900	  append(C,C0, C1),
  901	  U=[C1|Z1]
  902	).
  903
  904
  905% ?- find_cluster(a, [[a,b],[c,d]], C, X).
  906find_cluster(X,[],[X],[]).
  907find_cluster(X,[Y|Z],Y,Z):- memberchk(X,Y).
  908find_cluster(X,[Y|Z],U,[Y|V]):- find_cluster(X,Z,U,V).
  909
  910
  911	  /***************************
  912	  *     Reverse Automaton    *
  913	  ***************************/
  914
  915% Reversing coalgebra
  916% ?- am_flip([a-[b-c], d-[b-c], e-[b-c], x-[y-z]], R).
  917%@ R = [c-[b-[a, d, e]], z-[y-[x]]] .
  918% ?- am_flip([a-[b-c], d-[b-c], e-[m-c], x-[y-z]], R).
  919%@ R = [c-[b-[a, d], m-[e]], z-[y-[x]]] .
  920% ?- am_flip([a-[[], b-c, d-e, e-c], x-[y-z]], R).
  921%@ R = [c-[b-[a], e-[a]], e-[d-[a]], z-[y-[x]]] .
  922% ?- am_flip([a-[d-e, e-c], x-[y-z]], R).
  923%@ R = [c-[e-[a]], e-[d-[a]], z-[y-[x]]] .
  924% ?- am_flip([1-[a-1]], R).
  925% ?- am_flip([], X).
  926
  927am_flip --> am_flip_triples, triples_to_coa.
  928
  929%
  930am_flip_triples(X, Y):- maplist(am_flip_triples_aux, X, X0), 	append(X0, Y).
  931
  932%
  933am_flip_triples_aux(I-As, B):-
  934			fold_right(am_flip_triples_aux_aux(I), As, B, []).
  935
  936%
  937am_flip_triples_aux_aux(I, C-J, [J-(C-I)|W], W).
  938am_flip_triples_aux_aux(_, _,  W, W).
  939%
  940fold_right(_, [], P, P).
  941fold_right(F, [A|As], P, Q):- call(F, A, Q0, Q), fold_right(F, As, P, Q0).
  942
  943
  944% ?- am_reverse(coa([1-[[]]], 1), R).
  945%@ R = coa([1-[[]]], 1) .
  946% ?- am_reverse(coa([1-[a-2], 2-[b-3], 3-[[]]], 1), R).
  947%@ R = coa([1-[[]], 2-[a-1], 3-[b-2]], 3) .
  948
  949am_reverse(coa(E, I), Coa) :- am_flip(E,  E0),
  950	once((select(I-W, E0, E1);  W=[], E1=E0)),
  951	once(am_finals(coa(E, _), Is)),
  952	multi_entry_to_single(Is, [I-[[]|W]|E1], Coa0),
  953	am_fresh(Coa0, Coa1),
  954	am_clean(Coa1, Coa2),
  955	am_minimum(Coa2, Coa).
  956
  957%
  958multi_entry_to_single(Is, E, coa(D, Js))  :-
  959	am_clean(coa(E, _), coa(F, _)),
  960	sort(Is, Js),
  961	once(power_state_closure([Js], F, [], D)).
  962
  963% ?- power_state_closure([[1]], [1-[a-[1]]],  [], X).
  964% ?- power_state_closure([[1]], [1-[a-[2]], 2-[a-[1,2], b-[1]]], [], X).
  965
  966power_state_closure([], _, P, P).
  967power_state_closure([S|R], E, P, Q):- memberchk(S-_, P),
  968	power_state_closure(R, E, P, Q).
  969power_state_closure([S|R], E, P, Q):-
  970	power_state_closure_step(S, R, R0, E, P, P0),
  971	power_state_closure(R0, E, P0, Q).
  972
  973%
  974power_state_closure_step(S, R, R0, E, P, [S-A|P]):-
  975	merge_goto(S, E, [], A),
  976	foldl(power_state_closure_step_aux, A, R, R0).
  977
  978%
  979power_state_closure_step_aux(_-G, U, V):- memberchk(G, U), V=U; V=[G|U].
  980power_state_closure_step_aux([], U, U).
  981
  982% ?- merge_goto([1,2], [1-[a-[2,3]], 2-[a-[1,2], b-[3]]], [], X).
  983%@ X = [a-[1, 2, 3], b-[3]].
  984merge_goto([], _, A, A).
  985merge_goto([X|Xs], E, A, B):- memberchk(X-R, E),
  986	once(gdict_ord_merge(R, A, A0)),
  987	merge_goto(Xs, E, A0, B).
  988
  989% ?- gdict_ord_merge([[], a-[1,2], c-[3]], [a-[2,3], b-[2]], R).
  990gdict_ord_merge([], X, X).
  991gdict_ord_merge(X, [], X).
  992gdict_ord_merge([I-A|X], [I-B|Y], [I-C|Z]):- ord_union(A, B, C),
  993	gdict_ord_merge(X, Y, Z).
  994gdict_ord_merge([U|X], [U|Y], [U|Z]):-  gdict_ord_merge(X, Y, Z).
  995gdict_ord_merge([U|X], [V|Y], [U|Z]):-  U@<V,
  996	gdict_ord_merge(X, [V|Y], Z).
  997gdict_ord_merge([U|X], [V|Y], [V|Z]):-  gdict_ord_merge([U|X], Y, Z).
  998
  999%?- triples_to_coa([1-(a-4), 3-(c-3), 2-(b-1), 1-(a-2)], R).
 1000%@ R = [1-[a-[2, 4]], 2-[b-[1]], 3-[c-[3]]].
 1001triples_to_coa(X, Y):-sort(X, X0),
 1002	pairs_to_assoc(X0, Assoc, []),
 1003	maplist(triples_to_coa_aux, Assoc, Y).
 1004%
 1005triples_to_coa_aux(I-U, I-V):- pairs_to_assoc(U, V, []).
 1006
 1007%
 1008am_to_reversed_dag(E, D):- once(am_to_reversed_dag(E, [], Ps)),
 1009	sort(Ps, Ps0),
 1010	once(pairs_to_assoc(Ps0, D, [])).
 1011
 1012%
 1013am_to_reversed_dag([I-A|R], X, Y):- once(am_to_reversed_dag(A, I, X, X0)),
 1014	am_to_reversed_dag(R, X0, Y).
 1015am_to_reversed_dag([], X, X).
 1016
 1017%
 1018am_to_reversed_dag([_-G|R], I, X, Y):- am_to_reversed_dag(R, I, [G-I|X], Y).
 1019am_to_reversed_dag([_|R], I, X, Y):-  am_to_reversed_dag(R, I, X, Y).
 1020am_to_reversed_dag([], _, X, X).
 1021
 1022% ?- am_conflict_pairs([a-[[],1-a], b-[1-b], c-[[],1-a]], S).
 1023% ?- coa:am_conflict_pairs([a-[1-a], b-[1-b]], S).
 1024% ?- coa:am_conflict_pairs([a-[[]], b-[[]]], S).
 1025am_conflict_pairs(Coa, S):-
 1026	am_arity_dict(Coa, Dict),
 1027	once(arity_conflict_pairs(Dict, IniCon, [])),
 1028	sort(IniCon, IniCon0),
 1029	am_flip(Coa, RCoa),
 1030	once(propagate_conflict(IniCon0, RCoa, [], S)).
 1031
 1032% by agenda programming
 1033propagate_conflict([], _, P, P).
 1034propagate_conflict([U|R], Coa, P, Q):- memberchk(U, P),
 1035	propagate_conflict(R, Coa, P, Q).
 1036propagate_conflict([I-J|R], Coa, P, Q):-  memberchk(I-A, Coa),
 1037	memberchk(J-B, Coa),
 1038	fiber_product(A, B, F),
 1039	append(F, R, R0),
 1040	propagate_conflict(R0, Coa, [I-J|P], Q).
 1041propagate_conflict([U|R], Coa, P, Q):-
 1042	propagate_conflict(R, Coa, [U|P], Q).
 1043
 1044% ?- fiber_product([a-[7,8,9], b-[1,2,3]], [a-[6,7,8], b-[1,2,3]],  P).
 1045%@ P = [1-2, 1-3, 2-3, 6-7, 6-8, 6-9, 7-8, 7-9, 8-9] .
 1046
 1047fiber_product(A, B, P):- once(fiber_product(A, B, [], P0)),
 1048	sort(P0, P).
 1049
 1050fiber_product([], _,  P, P).
 1051fiber_product([X|Y], N,  P, Q):-
 1052	fiber_product_one(X, N, P, R),
 1053	fiber_product(Y, N, R, Q).
 1054%
 1055fiber_product_one([], _, P, P).
 1056fiber_product_one(_, [], P, P).
 1057fiber_product_one(X, [Y|Z], P, Q):-
 1058	fiber_product_one_one(X, Y, P, R),
 1059	fiber_product_one(X, Z, R, Q).
 1060%
 1061fiber_product_one_one(_, [], P, P).
 1062fiber_product_one_one(A-G, A-H, P, Q):-
 1063	s_product(G, H, P, Q).
 1064fiber_product_one_one(_, _, P, P).
 1065
 1066% ?- module(pac_word).
 1067% ?- pairs_to_assoc([1-[], 1-2, 1-3, 2-3, 2-4], X, []).
 1068%@ X = [1-[2, 3, []], 2-[3, 4]].
 1069pairs_to_assoc([], X, X).
 1070pairs_to_assoc([I-A|R], [I-As|V], V0):-
 1071	once(pairs_to_assoc(I, R, R0, [A], As)),
 1072	pairs_to_assoc(R0, V, V0).
 1073
 1074%
 1075pairs_to_assoc(I, [I-A|R], R0,  S, T):-
 1076	once(contract_insert(A, S, S0)),
 1077	pairs_to_assoc(I, R, R0, S0, T).
 1078pairs_to_assoc(_, R, R,  S, S).
 1079
 1080% ?- contract_insert(3, [2, 5, 7], R).
 1081%@ R = [2, 3, 5, 7].
 1082
 1083contract_insert(X, [], [X]).
 1084contract_insert(X, [X|S], [X|S]).
 1085contract_insert(X, [Y|S], [X, Y|S]):- X@<Y.
 1086contract_insert(X, [Y|S], [Y|R]):- contract_insert(X, S, R).
 1087
 1088
 1089% ?- all_states([1-[[],a-b], 2-[c-d]], R),
 1090all_states(X, S):- maplist(all_states_aux, X, S0), sort(S0, S).
 1091%
 1092all_states_aux(A-_, A).
 1093
 1094%
 1095arity(X, Y):- maplist(arity_aux, X, Y0), sort(Y0, Y).
 1096%
 1097arity_aux([], []).
 1098arity_aux(A-_, A).
 1099
 1100%
 1101am_arity_dict(Coa, Dict):- maplist(am_arity_dict_aux, Coa, Dict).
 1102%
 1103am_arity_dict_aux(I-X, I-M):- arity(X, M).
 1104
 1105% ?- arity_conflict_pairs([1-a, 2-b, 3-a, 4-b], A, []).
 1106arity_conflict_pairs([I-A|As], P, Q):- arity_conflict_pairs(I, A, As, P, P0),
 1107	arity_conflict_pairs(As, P0, Q).
 1108arity_conflict_pairs([], A, A).
 1109
 1110%
 1111arity_conflict_pairs(_, _, [], P, P).
 1112arity_conflict_pairs(I, A, [J-B|Bs], [I-J|P], Q):- A\==B,
 1113	arity_conflict_pairs(I, A, Bs, P, Q).
 1114arity_conflict_pairs(I, A, [_|Bs], P, Q):-
 1115	arity_conflict_pairs(I, A, Bs, P, Q).
 1116
 1117% ?-s_product([1,2,3],[1,2,3], P).
 1118%@ P = [1-2, 1-3, 2-3] .
 1119
 1120s_product(X, Y, P):- s_product(X, Y, [], Q), sort(Q, P).
 1121%
 1122s_product([], _, P, P).
 1123s_product([X|Xs], Y, P, Q):-
 1124	s_product(X, Xs, Y, P, R),
 1125	s_product(Xs, Y, R, Q).
 1126%
 1127s_product(X, Xs, Y, P, Q):-
 1128	foldl(s_product_aux(X), Y, P, R),
 1129	s_product(Xs, Y, R, Q).
 1130
 1131%
 1132s_product_aux(X, A, L, L):- A==X, !.
 1133s_product_aux(X, A, L, [W|L]):- s_pair(X, A, W).
 1134
 1135% ?- assoc_product([1,2,3], [1,2,3], R, []).
 1136%@ R = [1-[2, 3], 2-[3]] .
 1137
 1138assoc_product([], _, P, P).
 1139assoc_product(_, [], P, P).
 1140assoc_product([X|Xs], [Y|Ys], [X-[Y|Ys]|P], Q):- Y@>X,
 1141	assoc_product(Xs, [Y|Ys], P, Q).
 1142assoc_product(Xs, [_|Ys], P, Q):-assoc_product(Xs, Ys, P, Q).
 1143
 1144%  subtraction on assoc lists.
 1145% ?- assoc_subtract([1-[2,3,4], 2-[3,4], 3-[4,5,6]], [1-[3], 2-[4], 5-[6,7,8]], R).
 1146%@ R = [1-[2, 4], 2-[3], 3-[4, 5, 6]] .
 1147
 1148assoc_subtract([], _, []).
 1149assoc_subtract(A, [], A).
 1150assoc_subtract([I-A|Ps], [I-B|Qs], R):- once(ord_subtract(A, B, C)),
 1151	(	C == []
 1152	->      R = Rs
 1153	;	R = [I-C|Rs]
 1154	),
 1155	once(assoc_subtract(Ps, Qs, Rs)).
 1156assoc_subtract([I-A|Ps], [J-B|Qs], [I-A|Rs]):-  I@<J,
 1157	once(assoc_subtract(Ps,[J-B|Qs], Rs)).
 1158assoc_subtract([I-A|Ps], [_|Qs], [I-A|Rs]):-
 1159	once(assoc_subtract(Ps, Qs, Rs)).
 1160
 1161% ?-assoc_complement([1,2,3], [1-[2], 2-[3]], R).
 1162%@ R = [1-[3]] .
 1163
 1164assoc_complement(A, C, D):- assoc_product(A, A, AConf, []),
 1165	once(assoc_subtract(AConf, C, D)).
 1166
 1167%
 1168s_pair(A, B, A-B):- A @< B.
 1169s_pair(A, B, B-A).
 1170
 1171%
 1172am_char([], coa([1-[[]]], 1)).
 1173am_char(Is, coa([1-[[]|G], 2-[[]]], 1)):- maplist(am_char_aux, Is, G).
 1174
 1175am_char_aux(I, I-2).
 1176
 1177am_char_simple([], coa([1-[[]]], 1)).
 1178am_char_simple(Is, coa([1 - G, 2-[[]]], 1)):-
 1179	maplist(am_char_simple_aux, Is, G).
 1180%
 1181am_char_simple_aux(I, I-2).
 1182
 1183
 1184			/***************************************
 1185			*     automaton sysnthesis basics 2    *
 1186			***************************************/
 am_cap(+X:coa, +Y:coa, -Z:coa) is det
True if Z is unified with a coa intersection of X and Y.
 1192% digraph traversal by Agenda Programming.
 1193%
 1194am_cap(coa(E0, I0), coa(E1, I1), Coa):-
 1195	once(am_cap([I0*I1], [], E0, E1, [], E2)),
 1196	am_fresh(coa(E2, I0*I1), Coa0),
 1197	once(am_minimum(Coa0, Coa)).
 1198
 1199%
 1200am_cap([], _, _, _,  P, P).
 1201am_cap([U|R], H, A, B, P0, P):- memberchk(U, H),
 1202	am_cap(R, H, A, B, P0, P).
 1203am_cap([I*J|R], H, A, B,  P0, P):- memberchk(I-GI, A),
 1204	memberchk(J-GJ, B),
 1205	once(product_cap(GI, GJ, R0, R, Q, [])),
 1206	am_cap(R0, [I*J|H], A, B, [I*J-Q|P0], P).
 1207
 1208%
 1209product_cap([], _, R, R, Q, Q).
 1210product_cap(_, [], R, R, Q, Q).
 1211product_cap([[]|G], [[]|H], R0, R, [[]|Q0], Q):-
 1212	product_cap(G, H, R0, R, Q0, Q).
 1213product_cap([[]|G], H, R0, R, Q0, Q):-
 1214	product_cap(G, H, R0, R, Q0, Q).
 1215product_cap(G, [[]|H], R0, R, Q0, Q):-
 1216	product_cap(G, H, R0, R, Q0, Q).
 1217product_cap([U-I|G], [U-J|H], [I*J|R0], R, [U-I*J|Q0], Q):-
 1218	product_cap(G, H, R0, R, Q0, Q).
 1219product_cap([U-_|G], [V-I|H], R0, R, Q0, Q):- U@<V,
 1220	product_cap(G, [V-I|H], R0, R, Q0, Q).
 1221product_cap([U-I|G], [_|H], R0, R, Q0, Q):-
 1222	product_cap([U-I|G], H, R0, R, Q0, Q).
 am_minus(+X:coa, +Y:coa, -Z:coa) is det
True if Z is unified with a coa subtraction of X with Y.
 1228am_minus(coa(E0,I0), coa(E1, I1), Coa):-
 1229	once(am_minus([I0*I1], [], E0, E1, [], E2)),
 1230	append(E0, E2, E3),
 1231	am_determine(coa(E3, I0*I1), NCoa),
 1232	once(am_minimum(NCoa, Coa)).
 1233
 1234%
 1235am_minus([], _, _, _,  P, P).
 1236am_minus([U|R], H, A, B, P0, P):- memberchk(U, H),
 1237	am_minus(R, H, A, B, P0, P).
 1238am_minus([I*J|R], H, A, B,  P0, P):- memberchk(I-GI, A),
 1239	memberchk(J-GJ, B),
 1240	once(product_minus(GI, GJ, R0, R, Q, [])),
 1241	once(am_minus(R0, [I*J|H], A, B, [I*J-Q|P0], P)).
 1242
 1243%
 1244product_minus([], _, R, R, Q, Q).
 1245product_minus([W|G], [], R0, R, [W|P], Q):-
 1246	product_minus(G, [], R0, R, P, Q).
 1247product_minus([[]|G], [[]|H], R0, R, Q0, Q):-
 1248	product_minus(G, H, R0, R, Q0, Q).
 1249product_minus([[]|G], H, R0, R, [[]|Q0], Q):-
 1250	product_minus(G, H, R0, R, Q0, Q).
 1251product_minus(G, [[]|H], R0, R, Q0, Q):-
 1252	product_minus(G, H, R0, R, Q0, Q).
 1253product_minus([U-I|G], [U-J|H], [I*J|R0], R, [U-I*J|Q0], Q):-
 1254	product_minus(G, H, R0, R, Q0, Q).
 1255product_minus([U-I|G], [V-J|H], R0, R, [U-I|Q0], Q):- U@<V,   % bug fix [2014/08/23]
 1256	product_minus(G, [V-J|H], R0, R, Q0, Q).
 1257product_minus([U-I|G], [_|H], R0, R, Q0, Q):-
 1258	product_minus([U-I|G], H, R0, R, Q0, Q).
 am_cup(+X:coa, +Y:coa, -Z:coa) is det
True if Z is unified with a coa union of X and Y.
 1265am_cup(coa(A,I), Coa0,  Coa):-
 1266	length(A, N),
 1267	am_shift(N, Coa0, coa(C, K)),
 1268	append(A, C, D),
 1269	once(am_determine([[I,K]], [], D,  E, [])),
 1270	once(am_fresh(coa(E, [I,K]), Coa1)),
 1271	once(am_minimum(Coa1, Coa)).
 am_concat(+X:coa, +Y:coa, -Z:coa) is det
True if Z is unified with a concatenation of X and Y.
 1278% ?- am_concat(coa([1-[[], a-2], 2-[[]]],1),  coa([1-[a-2], 2-[[]]],1), R).
 1279% ?- am_concat(coa([1-[[], a-1]],1),  coa([1-[[], b-1]],1), R).
 1280
 1281am_concat(coa(E0, I0), Coa1, Coa):-once((
 1282	length(E0, N),
 1283	am_shift(N, Coa1, coa(E3, I3)),
 1284	memberchk(I3-G, E3),
 1285	maplist(am_replace_null(G), E0, E1),
 1286	append(E1, E3, E4),
 1287	am_slim(coa(E4,I0), E5),
 1288	am_determine(E5, E),
 1289	am_minimum(E, Coa))).
 am_power(+N:integer, +X:coa, -Y:coa) is det
True if Y is unified with a N times coa concatenation of X.
 1295am_power(N, X, Y):- poly:bits(N, [], Bs),
 1296	am_unit(U),
 1297	once(am_power(Bs, X, U, Y)).
 1298
 1299%
 1300am_power([], _, X, X).
 1301am_power([0|Bs], A, X, Y):-
 1302	am_concat(X, X, X2),
 1303	am_power(Bs, A, X2, Y).
 1304am_power([_|Bs], A, X, Y):-
 1305	am_concat(X, X, X2),
 1306	am_concat(A, X2, AX2),
 1307	am_power(Bs, A, AX2, Y).
 1308
 1309%
 1310am_power_lower(N, E, U):- am_unit(I),
 1311	am_cup(I, E, E0),
 1312	am_power(N, E0, U).
 1313
 1314am_power_upper(N, Coa, Coa0):-
 1315	am_power(N, Coa, Coa1),
 1316	am_star(Coa, Coa2),
 1317	am_concat(Coa1, Coa2, Coa0).
 1318
 1319am_power_between(I, J, Coa, Coa0):-
 1320	am_power(I, Coa, Coa1),
 1321	K is J - I,
 1322	am_power_lower(K, Coa, Coa2),
 1323	am_concat(Coa1, Coa2, Coa0).
 1324%
 1325am_unit(coa([1-[[]]], 1)).
 1326%
 1327am_empty(coa([], 0)).
 1328
 1329			/**************************
 1330			*     special automata    *
 1331			**************************/
 1332
 1333% ?- coa:am_shift(3, coa([1-[a-2, b-3]],1), R).
 1334%@ R = coa([4-[a-5, b-6]], 4).
 1335
 1336am_shift(N, coa(E,I), coa(E0, I0)):-
 1337	I0 is I+N,
 1338	maplist(state_id_shift(N), E, E0).
 1339
 1340%
 1341state_id_shift(N, I-A, J-B):- J is I + N,
 1342	maplist(goto_id_shift(N), A, B).
 1343
 1344%
 1345goto_id_shift(N, A-I, A-J):- J is I+N.
 1346goto_id_shift(_, X, X).
 1347
 1348%  ?- am_replace_null([a-2], 2-[[]], X).
 1349am_replace_null(A, I-[[]|B], I-C):-  ord_union(A, B, C).
 1350am_replace_null(_, P, P).
 am_kleene(+X:am, -Y:am) is det
True if Y is unified with a kleene closure of X.
 1357% ?- am_minimum(coa([1-[a-2, a-3, b-3], 2-[b-3], 3-[a-1]], 1), R).
 1358% ?- am_plus(coa([1-[a-2], 2-[[]]], 1), R).
 1359% ?- am_star(coa([1-[a-2], 2-[[]]], 1), R).
 1360% ?- am_star(coa([1-[a-2, b-3], 3-[[]], 2-[[]]], 1), R).
 1361% ?- am_star(coa([1-[a-2, a-3, b-3], 3-[[]], 2-[[]]], 1), R).
 1362% ?- am_star(coa([1-[a-2], 2-[[]]], 1), R).
 1363%@ R = coa([1-[[], a-1]], 1) .
 1364% ?- am_star(coa([1-[a-2, b-2], 2-[[]]], 1), R).
 1365%@ R = coa([1-[[], a-1, b-1]], 1) .
 1366% ?- am_plus(coa([1-[a-2, b-2], 2-[[]]], 1), R).
 1367%@ R = coa([1-[a-2, b-2], 2-[[], a-2, b-2]], 1) .
 1368% ?- am_copy(coa([1-[a-2], 2-[[]]], 1), D).
 1369
 1370
 1371am_kleene(coa(E, I), Coa):-
 1372	once(select(I-R, E, E0)),
 1373	once(drop_null(R, NR)),
 1374	maplist(am_replace_null([[]|NR]), E0, E1),
 1375 	once(am_determine(coa([I-R|E1], I), Coa)).
 1376
 1377%
 1378am_star(C, D):- am_kleene(C, coa(E0, I)),
 1379	once(select(I-R0, E0, E)),
 1380	(	R0=[[]|_]
 1381	->	R = R0
 1382	;	R = [[]|R0]
 1383	),
 1384	once(am_minimum(coa([I-R|E], I), D)).
 1385
 1386%
 1387am_plus(X, Y):- once((am_kleene(X, Z), am_minimum(Z, Y))).
 1388
 1389%
 1390am_fresh(coa([], _), C):- am_empty(C).
 1391am_fresh(coa(E, I), coa(E0, I0)):-
 1392	length(E, L),
 1393	numlist(1, L, Ns),
 1394	zip_hyphen(M, _, E),
 1395	zip_hyphen(M, Ns, S),
 1396	subst_coa(E, S, E0),
 1397	memberchk(I-I0, S).
 1398
 1399%
 1400am_fresh(Coa0, coa(E0, _), Coa):-  length(E0, N), am_shift(N, Coa0, Coa).
 1401
 1402%
 1403am_size(coa(E, _), N):- length(E, N).
 1404
 1405am_initial_state(coa(_, I), I).
 1406
 1407am_equations(coa(E, _), E).
 1408
 1409% ?- am_finals(coa([1-[[]], 2-[a-3], 3-[[]]], 1), R).
 1410%@ R = [1, 3] .
 1411% am_finals(coa(E, _), A):-
 1412% 	foldl(pred(	([I-H, [I|U], U] :- once(is_final_state(H)))
 1413% 		  &	[_, U, U]),
 1414% 		  E, A, []).
 1415
 1416am_finals(coa(E, _), A):- foldl(am_finals_aux, E, A, []).
 1417
 1418%
 1419am_finals_aux(I-H, [I|U], U) :- once(is_final_state(H)).
 1420am_finals_aux(_, U, U).
 1421
 1422%
 1423is_final_state(H):- memberchk([], H).
 1424is_final_state(H):- member(special(Spe), H),
 1425	final_special_pred(Spe).
 1426
 1427%  ?- am_states(coa([1-[[]], 2-[a-3], 3-[[]]], 1), R).
 1428%@ R = [1, 2, 3].
 1429am_states(coa(E, _), A):- maplist(am_states_aux, E, A).
 1430%
 1431am_states_aux(I-_, I).
 1432%
 1433am_copy(C,  D):-  C = coa(E0, _),
 1434	length(E0, N),
 1435	am_shift(N, C, D).
 1436%
 1437am_clean(coa(E, I),  coa(D, I)):- maplist(am_clean_aux,  E, E0),
 1438	sort(E0, D).
 1439
 1440am_clean_aux(J-A, J-B):-sort(A, B).
 1441
 1442%
 1443drop_null([[]|A], A).
 1444drop_null(A, A).
 1445
 1446%
 1447add_one(X, Y, Z):-  ( memberchk(X, Y)  ->  Z=Y ;   Z = [X|Y]).
 1448
 1449% ?-subst_coa([1-[b-2]], [1-9, 2-10], X).
 1450%@ X = [9-[b-10]].
 1451% ?-subst_coa([1-[[], b-2]], [1-9, 2-10], X).
 1452%@ X = [9-[[], b-10]].
 1453% ?- am_remove_useless_states(coa([1-[[], a-1, a-2], 2-[b-3], 3-[c-3]], 1), R).
 1454%@ R = coa([1-[[], a-1]], 1) .
 1455
 1456am_remove_useless_states(coa(E, I), coa(E0, I)):-
 1457	am_live_dead(coa(E,I), _, Dead),
 1458	am_remove_states(E, Dead, E0).
 1459
 1460am_live_dead(Coa, Live, Dead):- am_finals(Coa, Fs),
 1461	am_equations(Coa, E),
 1462	am_to_reversed_dag(E, Assoc),
 1463	once(dg_path_find(Fs, Assoc,  [], Live, Dead)).
 1464
 1465% ?- dg_path_find([], [1-[2], 2-[1]], [], X, Y).
 1466%@ X = [],
 1467%@ Y = [1, 2].
 1468% ?- dg_path_find([1], [1-[2], 2-[1], 3-[1,2]], [], X, Y).
 1469%@ X = [2, 1],
 1470%@ Y = [3].
 1471
 1472dg_path_find([], E, Live, Live, Dead):- maplist(dg_path_find_aux, E, Dead).
 1473dg_path_find([X|R], E,  Z,  Live, Dead):- memberchk(X, Z),
 1474	dg_path_find(R, E, Z, Live, Dead).
 1475dg_path_find([X|R], E, Z, Live, Dead):- select(X-G, E, E0),
 1476	union(G, R, R0),
 1477	dg_path_find(R0, E0, [X|Z], Live, Dead).
 1478dg_path_find([X|R], E, Z, Live, Dead):- dg_path_find(R, E, [X|Z], Live, Dead).
 1479
 1480dg_path_find_aux(I-_, I).
 1481
 1482% ?- am_connected_region(coa([1-[[]]], 1), C).
 1483% ?- am_connected_region(coa([1-[[], a-2], 2-[[]], 3-[a-3]], 1), C).
 1484
 1485am_connected_region(coa(E, I), coa(E0, I)):-
 1486	once(am_path_find([I], [], E, E0, [])).
 1487
 1488%
 1489am_path_find([],_H, _E, R, R).
 1490am_path_find(_, _H, [],  R, R).
 1491am_path_find([X|R], H, STS,  E0, E1):- memberchk(X, H),
 1492	am_path_find(R, [X|H], STS, E0, E1).
 1493am_path_find([X|R], H, STS,  [X-G|E0], E1) :- select(X-G, STS, STS0),
 1494	once(am_path_find_next(G, R0, R)),
 1495	am_path_find(R0, [X|H], STS0, E0, E1).
 1496am_path_find([X|R], H, STS,  [X|E0], E1) :- am_path_find(R, [X|H], STS, E0, E1).
 1497
 1498%
 1499am_path_find_next([_-G|R], [G|X], Y):- am_path_find_next(R, X, Y).
 1500am_path_find_next([_|R], X, Y):- am_path_find_next(R, X, Y).
 1501am_path_find_next([], X, X).
 1502
 1503% naive method.
 1504
 1505% ?- am_remove_empty_states(coa([], 1), C).
 1506%@ C = coa([], 1).
 1507% ?- am_remove_empty_states(coa([1-[[],a-2], 2-[]], 1), C).
 1508%@ C = coa([1-[[]]], 1) .
 1509% ?- am_remove_empty_states(coa([1-[[],a-2, a-3], 3-[b-2], 2-[]], 1), C).
 1510%@ C = coa([1-[[]]], 1) .
 1511
 1512am_remove_empty_states(coa(E, I), coa(E0,I)):-	am_elim_empty_states(E, E0).
 1513
 1514%
 1515am_elim_empty_states(E, E0):- am_elim_empty_states(E, S, [], E1, []),
 1516	(	S == []
 1517	->	E0 = E1
 1518	;   	once(am_elim_link(S, E1, E2)),
 1519		once(am_elim_empty_states(E2, E0))
 1520	).
 1521
 1522%
 1523am_elim_empty_states([], X, X, Y, Y).
 1524am_elim_empty_states([I-[]|R], [I|X], X0, Y, Y0):-
 1525	am_elim_empty_states(R, X, X0, Y, Y0).
 1526am_elim_empty_states([U|R], X, X0, [U|Y], Y0):-
 1527	am_elim_empty_states(R, X, X0, Y, Y0).
 1528
 1529%
 1530am_elim_link([], E, E).
 1531am_elim_link(Is, E, E0):- once(am_elim_link(Is, E, E0, [])).
 1532
 1533%
 1534am_elim_link(_, [], E, E).
 1535am_elim_link(Is, [I-A|R], [I-B|E], F):- once(elim_link_step(Is, A, B, [])),
 1536	am_elim_link(Is,  R, E, F).
 1537
 1538%
 1539elim_link_step(_,  [], X, X).
 1540elim_link_step(Is, [[]|R], [[]|X], Y):- elim_link_step(Is, R, X, Y).
 1541elim_link_step(Is, [_-S|R], X, Y):-  memberchk(S, Is),
 1542	elim_link_step(Is, R, X, Y).
 1543elim_link_step(Is, [I-S|R], [I-S|X], Y):- elim_link_step(Is, R, X, Y).
 1544
 1545% ?- am_remove_states([1-[a-2,b-2]], [1,2], R).
 1546% ?- am_remove_states([1-[[],a-2,b-2], 2-[b-1]], [1], R).
 1547am_remove_states([], _, []).
 1548am_remove_states([I-_|R], Ds, E):- memberchk(I, Ds),
 1549	am_remove_states(R, Ds, E).
 1550am_remove_states([I-A|R], Ds, [I-B|E]):- once(am_remove_goto(A, Ds, B)),
 1551	am_remove_states(R, Ds, E).
 1552
 1553%
 1554am_remove_goto([], _, []).
 1555am_remove_goto([[]|R], Ds, [[]|S]):- am_remove_goto(R, Ds, S).
 1556am_remove_goto([_-G|R], Ds, S):- memberchk(G, Ds),
 1557	am_remove_goto(R, Ds, S).
 1558am_remove_goto([U|R], Ds, [U|S]):- am_remove_goto(R, Ds, S).
 1559
 1560%
 1561subst_coa([], _, []).
 1562subst_coa([I-G|R], S, [I0-G0|R0]):- memberchk(I-I0, S),
 1563	subst_am_goto(G, S, G0),
 1564	subst_coa(R, S, R0).
 1565
 1566%
 1567subst_am_goto([A-I|R], S, [A-J|R0]):-  memberchk(I-J, S),
 1568	subst_am_goto(R, S, R0).
 1569subst_am_goto([X|R], S, [X| R0]):- subst_am_goto(R, S, R0).
 1570subst_am_goto([], _, []).
 1571
 1572			/****************************
 1573			*     characters classes    *
 1574			****************************/
 1575
 1576:- meta_predicate cook_char_dict(?, ?, 1, ?). 1577% ?- cook_char_dict(0, 127, atom, Dict),  maplist(([X]:- writeq(X), nl),  Dict).
 1578cook_char_dict(N0, N, Filter, 	Dict):- code_types(N0, N, Us),
 1579	collect(Filter, Us, Ts),
 1580	maplist(cook_char_dict_aux(N0, N), Ts, Dict).
 1581
 1582%
 1583cook_char_dict_aux(N0, N, T, T-CT):- collect_chars(N0, N, T, CT).
 1584
 1585%
 1586code_types(N0, N, S):- setof(T, C^ ( between(N0, N, C), code_type(C, T)), S).
 1587
 1588% ?- collect_chars(0, 10000, alpha, X).
 1589collect_chars(N0, N, CC, X):-
 1590	setof(C, (code_type(C, CC), between(N0, N, C)), S0),
 1591	zip_hyphen(S0, S0, S),
 1592	iboole:i_merge(S, Z0),
 1593	maplist(collect_chars_aux, Z0, X).
 1594
 1595collect_chars_aux(V0-W0,  V-W):- char_code(V, V0), char_code(W, W0).
 1596
 1597%
 1598reserved_char_class([
 1599	 alnum - ['0'-'9','A'-'Z',a-z],
 1600	 alpha - ['A'-'Z',a-z],
 1601	 ascii - ['\000\'-'\177\'],
 1602	 cntrl - ['\000\'-'\037\','\177\'-'\177\'],
 1603	 csym - ['0'-'9','A'-'Z','_'-'_',a-z],
 1604	 csymf - ['A'-'Z','_'-'_',a-z],
 1605	 digit - ['0'-'9'],
 1606	 end_of_line - ['\n'-'\r'],
 1607	 graph - [(!)-(~)],
 1608	 lower - [a-z],
 1609	 newline - ['\n'-'\n'],
 1610	 period - [(!)-(!), ('.')-('.'), (?)-(?)],
 1611	 prolog_atom_start - [a-z],
 1612	 prolog_identifier_continue - ['0'-'9','A'-'Z','_'-'_',a-z],
 1613	 prolog_symbol - [(#)- ($), (&)- (&), (*)- (+),
 1614			 (-)-(/), (:)-(:), (<)-(@),
 1615			 (\)-(\), (^)-(^), (~)-(~)],
 1616	 prolog_var_start - ['A'-'Z','_'-'_'],
 1617	 punct - [(!)-(/), (:)-(@),'['-('`'),'{'-(~)],
 1618	 quote - ['"'-'"','\''-'\'', ('`')-('`')],
 1619	 space - ['\t'-'\r',' '-' '],
 1620	 upper - ['A'-'Z'],
 1621	 white - ['\t'-'\t',' '-' '],
 1622	 utf8 - ['\200\' -  sup ],		% '
 1623	 hiragana - ['ぁ'-'ゔ'],
 1624	 katakana - ['ァ'-'ヺ'],
 1625	 kanji	- ['一'-'龠']
 1626]).
 1627
 1628utf8_byte_char_class([
 1629	 utf8   - ['\200\' - '\377\'],
 1630	 utf8c  - ['\200\' - '\277\'],
 1631	 utf8b  - ['\300\' - '\377\']
 1632	       ]).
 1633
 1634% ?-  C is 0xc0,  char_code(X, C).
 1635
 1636%
 1637look_ahead(C, [C|X], [C|X]).
 1638
 1639
 1640			/**************************************
 1641			*  compiling coalgebra into clause    *
 1642			**************************************/
+P:list, -Q:list) is det

True if G is unified with a compiled version of C with (K+2)-ary state predicates in P (minus Q).

A sample use: ?- expand_coa(0, [1-[[], [10-10]-1]], 1, user, G, P, []). G = user:'nt#52', P = [ user: ('nt#52'(_G6838, _G6838):-true), user: ('nt#52'([_G6868|_G6875], _G6877):- _G6868==10, 'nt#52'(_G6875, _G6877))] .
 1658%	?- expand_coa(0, [1-[[], [10-10]-1]], 1, user, G, P, []).
 1659expand_coa(K, C, I, M, M_G, P, Q):-
 1660	all_states(C, Nts),
 1661 	maplist(expand_coa_aux, Nts, Assoc),
 1662	memberchk(I-GI, Assoc),
 1663	void_states(C, Vs),
 1664	remove_void_state(C, I, C0),
 1665	compile_coa(C0, Vs, K, M, P, Q, Assoc),
 1666	prefix_convention(M, GI, M_G).
 1667
 1668expand_coa_aux(J, J-N):- new_nt_name(N).
 1669
 1670%
 1671remove_void_state([], _, []).
 1672remove_void_state([J-[[]]|C], Init, R):- J\==Init, !,
 1673	remove_void_state(C, Init, R).
 1674remove_void_state([X|C], Init, [X|R]):-
 1675	remove_void_state(C, Init, R).
 1676
 1677% ?- new_nt_name(X).
 1678new_nt_name(N):- var(N), nt_name_prefix(Prefix),
 1679				 gensym(Prefix, N).
 1680new_nt_name(_).
 1681
 1682%
 1683nt_name_prefix(N):- nb_current(nt_name_prefix, N),
 1684					 N \== [],
 1685					 !.
 1686nt_name_prefix('nt#').
 1687
 1688%
 1689insert_semicolon([X], X).
 1690insert_semicolon([X, Y|Z], X;U):- insert_semicolon([Y|Z], U).
 1691
 1692%
 1693compose_relation([X, Y], [X, X0], [X0, Y]).
 1694compose_relation([A, B, X, Y], [A, A0, X, X0], [A0, B, X0, Y]).
 1695
 1696prefix_convention([], P, P).
 1697prefix_convention(M, P, M:P).
 1698
 1699%
 1700void_states([], []).
 1701void_states([I-[[]]|R], [I|R0]):- void_states(R, R0).
 1702void_states([_|R], R0):- void_states(R, R0).
+P:list, -Q:list, +A:assoc) is det

True if G is unified with a compiled version of C with (K+2)-ary state predicates in P (minus Q). State id numbers are replaced by A.

?- compile_coa([1-[[], [10-20, 22-30]-1]], [], 2, user, P, [], [1- a]).

 1712compile_coa([],_, _, _, P, P, _).
 1713compile_coa([I-A|R], Vs, N, M,  P, Q, Assoc):-
 1714	memberchk(I-I0, Assoc),
 1715	once(compile_coa_state(I0, Vs, A, N, M, P, P0, Assoc)),
 1716	compile_coa(R, Vs, N, M, P0, Q, Assoc).
 1717%
 1718compile_coa_state(I, Vs,[X|A], N, M, P, Q, Assoc):-
 1719	once(compile_coa_state_one(I, Vs, X, N, M, P, P0, Assoc)),
 1720	compile_coa_state(I, Vs, A, N, M, P0, Q, Assoc).
 1721compile_coa_state(_, _, [], _, _, P, P, _).
 1722
 1723%
 1724compile_coa_state_one(I, _, [],  N, M, [R|P], P, _):-
 1725	compile_coa_epsilon_rule(N, I, R0),
 1726	once(prefix_convention(M, R0, R)).
 1727compile_coa_state_one(I, _, special(X), N, M, [Pred|P], P, _):-
 1728	once(compile_special_pred(X, [I, _, N, M], Pred)).
 1729compile_coa_state_one(I, Vs, A-J, N, M, P,  Q, Assoc):- is_list(A),
 1730	(	memberchk(J, Vs)
 1731	->	J0 = void_state
 1732	;  memberchk(J-J0, Assoc)
 1733	),
 1734	compile_coa_rule(A, I, J0, N, M, P, Q).
 1735
 1736%
 1737compile_coa_epsilon_rule(0, I, Head:- true):-
 1738	Head=..[I,X,X].
 1739compile_coa_epsilon_rule(2, I, Head:- true):-
 1740	Head=..[I, A, A, X, X].
 1741
 1742% ?- compile_coa_rule([10-20, 22-30], a, a, 2, user, P, []).
 1743compile_coa_rule([], _, _, _, _,P, P).
 1744compile_coa_rule([x(X, U)|A], I, J, N, M, P, Q):-
 1745	once(compile_special_char(X, U, N, I, J, M, P, P0)),
 1746	compile_coa_rule(A, I, J, N, M, P0, Q).
 1747compile_coa_rule(A, I, J, N, M, P, Q) :-
 1748	once(consecutive_intervals(A, Rest, B)),
 1749	compile_coa_intervals(B, I, J, N, M, P, P0),
 1750	compile_coa_rule(Rest, I, J, N, M, P0, Q).
 1751
 1752% ?- compile_coa_intervals([1-3], a, b, 0, user, P, []).
 1753% ?- compile_coa_interval(1, 3, a, b, 0, user, P, []).
 1754compile_coa_intervals([], _, _, _, _, P, P).
 1755compile_coa_intervals([L-U|A], I, J, N, M, P, Q):-
 1756	once(compile_coa_interval(L, U, I, J, N, M, P, P0)),
 1757	compile_coa_intervals(A, I, J, N, M, P0, Q).
 1758
 1759%
 1760narrow_interval(L, U):- integer(L),
 1761						integer(U),
 1762						L + 5  >  U.
 1763
 1764compile_coa_interval(L, U, I, J, N, M, P, Q):- narrow_interval(L, U), !,
 1765	compile_interval_smart(L, U, I, J, N, M, P, Q).
 1766compile_coa_interval(L, U, I, J, N, M, [R|T], T):-
 1767	once(generate_code_test([L-U], V, Cond)),
 1768	(	N==0, Head =..[I, [V|Z], Z0]
 1769	;	N==2, Head =..[I, [V|W], W0, [V|Z], Z0]
 1770	),
 1771	(	J==void_state, Call = true
 1772	;	N==0, Call=..[J, Z, Z0]
 1773	;	N==2, Call=..[J, W, W0, Z, Z0]
 1774	),
 1775	(	J==void_state, Z0=Z, W0=W
 1776	; true
 1777	),
 1778	slim_goal((Cond, Call), Body),
 1779	prefix_convention(M, Head:- Body, R).
 1780
 1781% ?- compile_interval_smart(1, a, b, 2, user, P, []).
 1782% ?- compile_interval_smart(1, a, void_state, 2, user, P, []).
 1783% ?- compile_interval_smart(1, a, b, 0, user, P, []).
 1784% ?- compile_interval_smart(1, a, void_state, 2, user, P, []).
 1785
 1786compile_interval_smart(D, I, J, N, M, [Cls|P], P):-
 1787		(	N==0, Head =..[I, [D|Z], Z0]
 1788		;	N==2, Head =..[I, [D|W], W0, [D|Z], Z0]
 1789		),
 1790		(	J==void_state, Call = true
 1791		;	N==0, Call=..[J, Z, Z0]
 1792		;	N==2, Call=..[J, W, W0, Z, Z0]
 1793		),
 1794		(	J==void_state, Z0=Z, W0=W
 1795		; true
 1796		),
 1797		prefix_convention(M, Head:- Call, Cls).
 1798
 1799% ?- compile_interval_smart(1, 2, a, void_state, 2, user, P, []).
 1800% ?- compile_interval_smart(1, 2, a, b, 2, user, P, []).
 1801
 1802compile_interval_smart(L, U, I, J, N, M, P, Q):- L=<U, !,
 1803		compile_interval_smart(L, I, J, N, M, P, P0),
 1804		L0 is L + 1,
 1805		compile_interval_smart(L0, U, I, J, N, M, P0, Q).
 1806compile_interval_smart(_, _, _, _, _, _, P, P).
 1807
 1808% ?-  consecutive_intervals([a-b, b-c, c], X, Y).
 1809consecutive_intervals([], [], []).
 1810consecutive_intervals([A-B|R], U, [A-B|V]):- consecutive_intervals(R, U, V).
 1811consecutive_intervals([X|R], [X|R], []).
 1812
 1813%
 1814goto_argument_form(0, V, [[V|R], S], [R, S]).
 1815goto_argument_form(2, V, [[V|A], B, [V|R], S], [A, B, R, S]).
 1816
 1817% ?- generate_code_test([1-1], V, C).
 1818% ?- generate_code_test([1-1, 4-4], V, C).
 1819% ?- generate_code_test([(1-4)\2], V, C).
 1820generate_code_test(A-B, V, C):- generate_code_test([A-B], V, C).
 1821generate_code_test(Is, V, C):- adjacent_interval(Is, Js, []),
 1822	maplist(generate_code_test_aux(V), Js, Ks),
 1823	insert_semicolon(Ks, C).
 1824
 1825%
 1826generate_code_test_aux(V, X, Y):- once(generate_code_between(X, V, Y)).
 1827
 1828
 1829% ?- adjacent_interval([1-2, 4-5, 7-9, 11-13], P, []).
 1830% ?- adjacent_interval([1-2, 4-5, 7-9, 11-13, 15-17], P, []).
 1831
 1832adjacent_interval([], X, [X|P], P).
 1833adjacent_interval([A-B|R], C-D, [(C-B)\X|P], Q):-  C\==D,
 1834	succ_transitive(D, X, A),
 1835	adjacent_interval(R,  P, Q).
 1836adjacent_interval(X, U, [U|P], Q):-
 1837	adjacent_interval(X, P, Q).
 1838
 1839%
 1840adjacent_interval([U|R], P, Q):- adjacent_interval(R, U, P, Q).
 1841adjacent_interval([], P, P).
 1842
 1843%
 1844succ_transitive(A, X, B):-   plus(A, 2, B), plus(A, 1, X).
 1845
 1846%
 1847generate_code_between(inf-sup, _,	true).
 1848generate_code_between(inf-A, V,		V @=< A).
 1849generate_code_between(A-sup, V,		A @=< V).
 1850generate_code_between(A-A,  V,		V == A).
 1851generate_code_between(A-B,  V,		(A @=< V, V @=<B)).
 1852generate_code_between((A-B)\W,  V,	BCode0):-
 1853	once(generate_code_between(A-B, V, BCode)),
 1854	( BCode == true, BCode0 = (V\== W)
 1855	; BCode0 = (V\==W, BCode)).
 1856
 1857			/*************
 1858			*     sed    *
 1859			*************/
 1860
 1861% ?- expand_phrase(sed(@(s/"a"/"b")), [], G, L, []).
 1862% ?- phrase(sed(w("[afl]") >> [[]]), `abcdefghijklmn`,  V), basic:smash(V).
 1863% ?- phrase(sed(w(".+", A)>> pred(A, [[A,A]])), `ab`,  V), basic:smash(V).
 1864% ?- phrase(sed((w(".", A), w(".", B))>> pred([A,B],([C]:- append(B, A, C)))), `ab12`,  V), basic:smash(V).
 1865% ?- phrase(sed((w(".", A), w(".", B))>> append(B, A)), `abcdefghijklmn`,  V), basic:smash(V).
 1866% ?- phrase(sed(w("[afl]")>> pred([[]])), `abcdefghijklmn`,  V), basic:smash(V).
 1867% ?- phrase(sed(wl("\\\\[a-zA-Z]*")>> pred([[]])), `\\abcdefghijklmn`,  V), basic:smash(V).
 1868% ?- phrase(sed(w("a")>>(user:pred([`x`]))), `abaaa`,  V), basic:smash(V).
 1869% ?- show(phrase(sed(w("a")>>pred([`x`])))).
 1870% ?- show_phrase(sed((w(".", A), w(".", B))>>append(B, A))).
 1871% ?- show_phrase(sed(w("a")>>pred([`x`]))).
 1872% ?- show_phrase(w("a*")).
 1873% ?- show_am("\\\\[a-zA-Z]*").
 1874% ?- show_am("[a-zA-Z]*").
 1875
 1876expand_recognize_act(Vars, Words, Words_in_pac,  Mod,  Rec_Act, List, List3):-
 1877	recognize_act(Vars, Words, Words_in_pac,  Mod,  R_A, List, List1),
 1878    expand_core( rec(Sed_name, Vars,
 1879				 	 ([[acc(Acc)|M], M, acc(Acc,[]), []])
 1880				 &	 ([M, M, [], []])
 1881				 &	 ( [L, M, P, Q]  :-  call(R_A, L, L0, P, P0), !,
 1882                                         call(Sed_name, L0, M, P0, Q))
 1883	             &	 ( [[C|Z0], Z, [C|P], Q]:- !, call(Sed_name, Z0, Z, P, Q))
 1884	             &	 ( [[C|Z0], Z, acc(V,[C|P]), Q]:-
 1885						   call(Sed_name, Z0, Z, acc(V, P), Q))
 1886					),
 1887                Mod, Sed_main, List1, List2),
 1888    expand_core( pred(Vars, [U,V]:- call(Sed_main, V, [], U, [])),
 1889                 Mod, Rec_Act, List2, List3).
 1890
 1891% The prefix 'user:' is for get_acc to be found in runtime .
 1892user:get_acc(V, acc(V,L), L):-!.
 1893user:get_acc([], L, L).
 1894%
 1895user:get_acc(V, _, acc(V,L), L):-!.
 1896user:get_acc(I, I, L, L).
 1897%
 1898user:set_acc(V, L, acc(V, L)).
 1899
 1900% ?- recognize_act([], "a",  "b", user, A, P, []).
 1901recognize_act(Vars, Words, Action,  Mod,  Recog_Act, List, List3):-
 1902	once(expand_sed_act(Action, Mod, Action_expanded, List, List0)),
 1903	lazy_prepend(Action_expanded, Action_slim, L, L0),
 1904	expand_phrase(Words, Mod, Phrase, List0, List1),
 1905	phrase_to_pred(Phrase, Mod, ([P, P0]:- Expanded_phrase), List1, List2),
 1906	expand_core(pred(Vars, ([L, L0, P, P0]:-
 1907				    once(Expanded_phrase), once(Action_slim))),
 1908		    Mod, Recog_Act, List2, List3).
 1909
 1910%
 1911expand_sed_act(X, _, X, L, L):- (var(X); number(X); string(X); is_list(X)), !.
 1912expand_sed_act(X + Y, M, X0 + Y0, L, L0):-
 1913	expand_sed_act(X, M, X0, L, L1),
 1914	expand_sed_act(Y, M, Y0, L1, L0).
 1915expand_sed_act(X, M, Y, L, L0):- expand_arg(X, M, Y, L, L0).
 1916
 1917% ?- expand_head_sed([], ("a"), "b", user, G, List, []), pac:show(G, List).
 1918% ?- expand_head_sed([], ("a"), "b", user, G, List, []), !, maplist(assert, List), call(G, X, `a`, []).
 1919% ?- expand_head_sed([A], ("a"), "b", user, G, List, []), !, maplist(assert, List), call(G, X, `a`, []).
 1920
 1921
 1922expand_head_sed(Vars, Words, Action,  Mod,  G_callable, List, List3):-
 1923	expand_phrase(Words, Mod, Phrase, List, List0),
 1924	expand_sed_act(Action, Mod, Action_expanded, List0, List1),
 1925	lazy_prepend_slim(Action_expanded, Action_slim, L, []),
 1926	phrase_to_pred(Phrase, Mod,
 1927		       [P, P0]:- Expanded_phrase, List1, List2),
 1928	expand_core(pred(Vars, ([L, P, P0]:- Expanded_phrase, Action_slim)),
 1929		    Mod, G_callable, List2, List3).
 1930
 1931% ?- word((=([a,b]), =([c,d])), X, []).
 1932word((A, B), X, Y):-  word(A, X, Z), word(B, Z, Y).
 1933word(A, X, Y):- string(A), string_codes(A, C), append(C, Y, X).
 1934word(A, X, Y):- call(A, S), append(S, Y, X).
?- lazy_prepend_slim("abc", A, V, V0). ?- lazy_prepend_slim([abc], A, V, V0). ?- lazy_prepend_slim(abc, A, V, V0). ?- lazy_prepend_slim(abc+xyz, A, V, V0). ?- lazy_prepend_slim(X+Y, A, V, V0).
 1943lazy_prepend_slim(E, A, V, V0):- once(lazy_prepend(E, B, V, V0)),
 1944			  slim_goal(B, A).
 1945%
 1946lazy_prepend(X, basic:prepend(X, Y, Z), Y, Z):- var(X), !.
 1947lazy_prepend(X, true, P, Q):- is_list(X), !, basic:prepend(X, P, Q).
 1948lazy_prepend(X, true, [X|Y], Y):- string(X), !.
 1949lazy_prepend(X, true, [X0|Y], Y):- number(X), !, number_string(X,X0).
 1950lazy_prepend(X + Y, (A, B), P, Q):- lazy_prepend(X, A, P, P0),
 1951				    lazy_prepend(Y, B, P0, Q).
 1952lazy_prepend(X, (C, basic:prepend(Z, P, Q)),  P, Q):- complete_args(X, [Z], C).
 1953
 1954% ?- phrase(sed(b/"a"/"hello"), ` a a `, R), basic:smash(R).
 1955% ?- phrase(sed(a/"a"/"hello"), ` a a `, R), basic:smash(R).
 1956% ?- phrase(sed(w/"a"/"hello "/" world"), ` a a `, R), basic:smash(R).
 1957% ?- phrase(sed(wl/"a"/"hello "/" world"), ` a a `, R), basic:smash(R).
 1958% ?- sed((wl/"a"/"hello "/" world"), ` a a `, R), basic:smash(R).
 1959% ?- sed((wl/("a", X)/"hello "/" world"), ` a a `, R), basic:smash(R).  % << error test.
 1960
 1961
 1962
 1963			/***************
 1964			*     regex    *
 1965			***************/
 expand_w(+X:regex, +M:atom, -G:goal, -P:list, -Q:list) is det
True if G is unifed with a goal and helper predicates are created in P (minsu Q) so that calling G behaves as X in the shortest-match-mode.
 1974% ?- phrase((w(*(.), X), w(*(.), Y)),  [a,b,c], []).
 1975% ?- phrase((wl(*(.), X), wl(*(.), Y)),  [a,b,c], []).
 1976
 1977% ?- expand_w("a*$", [], G, P, []).
 1978% ?- phrase(w("a*"), `aaaaab`, R).
 1979% ?- expand_w("a*", A, [], [],  G, P, []).
 1980
 1981expand_w(X, _, call(X), P, P):-var(X).	% @ meta call
 1982expand_w(X, M, G, P, Q):-
 1983	regex_coalgebra_code(X, coa(C, I, _)),
 1984	expand_coa(0, C, I, M, G, P, Q).
 expand_w(+X:regex, -A:var, -B:var, +M:atom, -G:goal, +P:list, -Q:list) is det
True if G is unifed with a goal and helper predicates are created in P (minsu Q) so that calling G behaves as X in the shortest-match-mode with d-list (A, B).
 1992expand_w(X, A, B, _, call(X, A, B), P, P):- var(X).  % @ meta call
 1993expand_w(X, A, B, M, G, P, Q):-
 1994	regex_coalgebra_code(X, coa(C, I, _)),
 1995	expand_coa(2, C, I, M, G0, P, Q),
 1996	complete_args(G0, [A, B], G).
 expand_wl(+X:regex, +M:atom, -G:goal, -P:list, -Q:list) is det
True if G is unifed with a goal and helper predicates are created in P (minsu Q) so that calling G behaves as X in the longest-match-first mode.
 2004expand_wl(X, _, call(X), P, P):-var(X).	% @ meta call
 2005expand_wl(X, M, G, P, Q):-
 2006	regex_coalgebra_code(X, coa(C, I, _)),
 2007	null_last_coa(C, C0),
 2008	expand_coa(0, C0, I, M, G, P, Q).
 expand_wl(+X:regex, A:var, B:var, +M:atom, -G:goal, -P:list, -Q:list) is det
True if G is unifed with a goal and helper predicates are created in P (minsu Q) so that calling G behaves as X in the longest-match-first mode with d-list (A, B)
 2016expand_wl(X, A, B, _, call(X, A, B), P, P):- var(X).  % @ meta call
 2017expand_wl(X, A, B, M, G, P, Q):-
 2018	regex_coalgebra_code(X, coa(C, I, _)),
 2019	null_last_coa(C, C0),
 2020	expand_coa(2, C0, I, M, G0, P, Q),
 2021	complete_args(G0, [A, B], G).
 2022
 2023%
 2024null_last_coa(X, Y):- maplist(null_last_coa_state, X, Y).
 2025
 2026%
 2027null_last_coa_state(A-B, A-C):- reverse(B, C).
 2028
 2029	  /***********************
 2030	  *     compare regex    *
 2031	  ***********************/
 2032
 2033% ?- regex_compare(C, "a", "a").
 2034% ?- regex_compare(C, "a", "b").
 2035% ?- regex_compare(C, "a*", "a").
 2036regex_compare(C, X, Y):- regex_normal_am_list([X,Y], [X0, Y0]),
 2037	once(am_compare(C, X0, Y0)).
 2038
 2039% ?-  regex_normal_am_list(["a", "b"], R).
 2040% ?-  regex_normal_am_list(["(ab)*", "b"], R).
 2041
 2042regex_normal_am_list(X, Y):- regex_word(regexlist(X), regexlist(X0)),
 2043	maplist(word_normal_am, X0, Y).
 2044
 2045
 2046	  /***************************
 2047	  *     bisimilarity test    *
 2048	  ***************************/
 2049
 2050% ?- am_bisimilar(coa([], 0), coa([], 1)).
 2051% ?- am_bisimilar(coa([1-[[]]], 1), coa([1-[[]]], 1)).
 2052% ?- (regex_am("a", R), am_bisimilar(R, R)).
 2053% ?- (regex_am(a+ (+a), R), regex_am((+a)+a, S), !,  am_bisimilar(R, S)).
 2054% ?- (regex_am(a+ (+a), R), regex_am((+a)+a+a, S), !,  am_bisimilar(R, S)).
 2055
 2056am_bisimilar(coa([], _), coa([], _)).
 2057am_bisimilar(coa(E, I), coa(F, J)):-
 2058	once(bisimilar(I, J, [], _, E, F)).
 2059
 2060%
 2061bisimilar(I, J, Done, Done, _, _):- memberchk(I-J, Done).
 2062bisimilar(I, J, Done , Done0, E, F):-
 2063	memberchk(I-G, E),
 2064	memberchk(J-H, F),
 2065	bisimilar_down(G, H, [I-J|Done], Done0, E, F).
 2066%
 2067bisimilar_down([], [], Done, Done, _, _).
 2068bisimilar_down([[]|R], [[]|S], Done, Done0, E, F):-
 2069	bisimilar_down(R, S, Done, Done0, E, F).
 2070bisimilar_down([C-I|R], [C-J|S], Done, Done0, E, F):-
 2071	bisimilar(I, J, Done, Done1, E, F),
 2072	bisimilar_down(R, S, Done1, Done0, E, F).
 2073
 2074	  /*********************************
 2075	  *     one-way similarity test    *
 2076	  *********************************/
 2077
 2078% ?- (regex_am("a", A), regex_am("b", B), am_compare(C, A, B)).
 2079% ?- (regex_am("a", A), regex_am("a", B), am_compare(C, A, B)).
 2080% ?- (regex_am("a", A), regex_am("a*", B), am_compare(C, A, B)).
 2081% ?- (regex_am("a*", A), regex_am("a", B), am_compare(C, A, B)).
 2082am_compare(C, A, B):- once(am_similar(A, B)),
 2083	(	am_similar(B, A)
 2084	->	C = (=)
 2085	;	C = (<)
 2086	).
 2087am_compare(C, A, B):- am_similar(B, A) -> C = (>); C = incomparable.
 2088
 2089%
 2090am_similar(coa([], _), coa([], _)).
 2091am_similar(coa(E, I), coa(F, J)):-
 2092	similar(I, J, [], _, E, F).
 2093
 2094%
 2095similar(I, J, Done, Done, _, _):- memberchk(I-J, Done).
 2096similar(I, J, Done , Done0, E, F):-
 2097	memberchk(I-G, E),
 2098	memberchk(J-H, F),
 2099	once(similar_down(G, H, [I-J|Done], Done0, E, F)).
 2100%
 2101similar_down([], _, Done, Done, _, _).
 2102similar_down([[]|R], [[]|S], Done, Done0, E, F):-
 2103	similar_down(R, S, Done, Done0, E, F).
 2104similar_down([C-I|R], [C-J|S], Done, Done0, E, F):-
 2105	similar(I, J, Done, Done1, E, F),
 2106	similar_down(R, S, Done1, Done0, E, F).
 2107similar_down(R, [_|S], Done, Done0, E, F):-
 2108	similar_down(R, S, Done, Done0, E, F)