since the grammar is not left recursive, we can use a DCG:
s --> a.
a --> [m], a, [n].
a --> [o].
then we can parse or generate all accepted sequences. For instance, generating:
?- length(L, _), phrase(s, L).
L = [o]
L = [m, o, n]
L = [m, m, o, n, n]
...
to inspect the Prolog code:
?- listing(s).
s(A, B) :-
a(A, B).
?- listing(a).
a([m|A], C) :-
a(A, B),
B=[n|C].
a([o|A], A).
no append/3 required, thanks to difference lists
edit using append/3
s(Z) :- a(Z).
a(Z) :- append([m|X],[n],Z), a(X).
a([o]).
SWI-Prolog has append/2 (simply based on append/3 properly chained), that give
a more readable alternative
a(Z) :- append([[m],X,[n]], Z), a(X).
anyway, we must call a/1 recursively after the list has been built/split
A(Z)
, buta(Z)
. Similarly with all predicate names... – Orsa