考虑以下列表:
[我的,名称,是,千斤顶,鲍尔]
我想将其统一为以下模式:
[我的,名称,是,名称]
因此变量Name最后的值为'jack baur'。 该变量在这里作为某种通配符工作,并且应该与未知数量的原子/列表成员统一。
重要:
目前我有这样的事情:
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).
显然,只有当Name
只是一个单词而不是两个单词时,这才有效。
我如何在Prolog中解决这个问题?
答案 0 :(得分:1)
您需要自定义统一算法,例如:
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).
用法:
1 ?- unify([i, am, a, Profession, and, i, Verb, it],
[i, am, a, prolog, programmer, and, i, like, it]).
Profession = [prolog, programmer],
Verb = [like].
为了提高效率,此算法仅允许变量出现在L
中。我会留下将原子粘贴在一起的问题,因为你似乎已经解决了这个问题。
请注意,当前版本允许变量匹配零原子,但您可以轻松添加约束以禁止它。
答案 1 :(得分:1)
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), !.
用
?- answer([my, name, is, bill, the, kid, and, i, live, in, new, york],R).
R = [hello, bill, the, kid, of, new, york].
这里的基本生产是列表// 1,匹配任何明确长度的令牌列表。
注意:list(A),list(B),
,两者 A,B应该避免未绑定。
如果中间有令牌,就像在list(A),[and],list(B),