You're on the right track, you just need a way to deal with the difference in counts. You can do this by adding a numeric argument to your palindromes
grammar term.
First I'll define an ordinary Prolog rule implementing "B
is two more than A
":
plus2(A,B) :- number(A), !, B is A+2.
plus2(A,B) :- number(B), !, A is B-2.
plus2(A,B) :- var(A), var(B), throw(error(instantiation_error,plus2/2)).
Then we'll say palindromes(Diff)
means any palindrome on the given alphabet where the number of b
letters minus the number of a
letters is Diff
. For the base cases, you know Diff
exactly:
palindromes(0) --> [].
palindromes(-1) --> [a].
palindromes(1) --> [b].
For the recursive grammar rules, we can use a code block in {
braces}
to check the plus2
predicate:
palindromes(DiffOuter) --> [b], palindromes(DiffInner), [b],
{ plus2(DiffInner, DiffOuter) }.
palindromes(DiffOuter) --> [a], palindromes(DiffInner), [a],
{ plus2(DiffOuter, DiffInner) }.
To finish off, the top-level grammar rule is simply
please --> palindromes(1).