Question

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:

  • the variable/wildcard is not always at the end
  • there could be multiple variables/wildcards

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?

Was it helpful?

Solution

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),

OTHER TIPS

You need a custom unification algorithm, such as the following:

unify([], []).
unify([X|L], R) :-
    (var(X) ->
        % unify the variable X with some prefix of R
        append(X, Tail, R),
    ;
        R = [X|Tail],
    ),
    unify(L, Tail).

Usage:

1 ?- unify([i, am, a, Profession, and, i, Verb, it],
           [i, am, a, prolog, programmer, and, i, like, it]).
Profession = [prolog, programmer],
Verb = [like].

This algorithm only allows variables to occur in L for the sake of efficiency. I'll leave the problem of pasting atoms together to you, since you seem to have already solved that.

Note that the current version allows variables to match zero atoms, but you can easily add a constraint to disallow that.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top