Reputation: 710
How would I go about finding consecutive repetition of a string in a list in prolog.
What I'm exactly trying to find, for example, is this:
input => output
AAAAAA => 6*(A)
ABABAB => 3*(AB)
ABCABCABC => 3*(ABC)
I wrote a DCG grammar for this and I'm trying to have it give me this as a result.
Here's the grammar, if needed:
exp --> term.
exp --> term, [+], exp.
term --> factor.
term --> digit, [*], exp.
factor --> elem.
factor --> ['S'], ['['], sym, [']']. %S[(A)(B),(C)]
factor --> ['<'], alt, ['>'], ['/'], ['<'], alt, ['>']. %<(A)>/<(B)(C)(D)>
factor --> ['('], exp, [')'].
sym --> factor.
sym --> factor, [','], factor.
sym --> factor, sym.
alt --> factor.
alt --> factor, alt.
elem --> char.
elem --> char, elem.
char --> [D], {is_alnum(D)}.
digit --> [D], {is_alnum(D)}.
digit --> [D], {number(D)}.
nbr_to_char(N, Cs) :-
name(Cs, [N]).
str_to_list(S, Cs) :-
name(S, Xs),
maplist(nbr_to_char, Xs, Cs).
eval(L) :-
str_to_list(L, X),
exp(X, []).
Thanks for any help.
Upvotes: 2
Views: 156
Reputation: 60004
I think what you're after is pack(dcg_util). But also consider append/2:
?- A=`ababab`.
A = [97, 98, 97, 98, 97, 98].
?- append([X,X,X],$A).
X = [97, 98],
A = [97, 98, 97, 98, 97, 98] ;
false.
Now, if we just find an easy way to make lists of repeated variables, we have a fairly powerful construct, we can use to tackle to problem. Let's try:
?- length(L,3),maplist(=(X),L).
L = [X, X, X].
So:
?- length(L,_),maplist(=(X),L),append(L,$A).
L = [[97, 98, 97, 98, 97, 98]],
X = A, A = [97, 98, 97, 98, 97, 98] ;
L = [[97, 98], [97, 98], [97, 98]],
X = [97, 98],
A = [97, 98, 97, 98, 97, 98] ;
^CAction (h for help) ? abort
% Execution Aborted
oops, never ending story... but a bit boring. Need a bit more code, enforcing the domain knowledge (bagging, really...)
?- length($A,U),between(1,U,N),length(L,N),maplist(=(X),L),append(L,$A).
U = 6,
N = 1,
L = [[97, 98, 97, 98, 97, 98]],
X = A, A = A, A = [97, 98, 97, 98, 97, 98] ;
U = 6,
N = 3,
L = [[97, 98], [97, 98], [97, 98]],
X = [97, 98],
A = A, A = [97, 98, 97, 98, 97, 98] ;
false.
Upvotes: 2