Consider the following list:
[my,name,is,jack,baur]
I want to unify this to the following pattern:
[my,name,is,Name]
So that the variable Name has the value 'jack baur' in the end. The variable is working as some sort of wildcard here and should unify with an unknown number of atoms/list members.
Important:
Currently I have something like this:
rule([my,name,is,Name],[hello,Name]).
% Sentence is a list (e.g. [my,name,is,jack,baur]
answer(Sentence,Response) :-
rule(Sentence,ResponseList),
atomic_list_concat(ResponseList,' ',Response).
Obviously this only works when Name
is exactly one word, not two.
How would I approach this problem in Prolog?
here a DCG possibility. It's fairly clean, I think.
list(L) --> {length(L, _)}, L.
rule(R) -->
[my, name, is], list(Name),
[and, i, live, in], list(Country),
{flatten([hello, Name, of, Country],R)}.
rule([hello|Name]) -->
[my, name, is], list(Name) .
answer(Sentence, Response) :-
phrase(rule(Response), Sentence), !.
with that
?- answer([my, name, is, bill, the, kid, and, i, live, in, new, york],R).
R = [hello, bill, the, kid, of, new, york].
the essential production here is list//1, that matches any definite length list of tokens.
Beware: list(A),list(B),
, with both A, B unbound should be avoided.
It's ok instead if there are tokens in between, like in list(A),[and],list(B),