List 通过连接原子统一不同长度的列表
考虑以下列表: [我的名字是,杰克,鲍尔] 我想将其统一为以下模式: [我的,名字,是,名字] 因此,变量名最后的值为“jack baur”。 变量在这里作为某种通配符工作,应该与未知数量的原子/列表成员统一 重要提示:List 通过连接原子统一不同长度的列表,list,prolog,wildcard,matching,dcg,List,Prolog,Wildcard,Matching,Dcg,考虑以下列表: [我的名字是,杰克,鲍尔] 我想将其统一为以下模式: [我的,名字,是,名字] 因此,变量名最后的值为“jack baur”。 变量在这里作为某种通配符工作,应该与未知数量的原子/列表成员统一 重要提示: 变量/通配符并不总是在末尾 可能有多个变量/通配符 目前我有这样的想法: rule([my,name,is,Name],[hello,Name]). % Sentence is a list (e.g. [my,name,is,jack,baur] answer(Sent
- 变量/通配符并不总是在末尾
- 可能有多个变量/通配符
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中如何处理这个问题?您需要一个自定义的统一算法,例如:
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
中。我将把粘贴原子的问题留给你们,因为你们似乎已经解决了这个问题
请注意,当前版本允许变量匹配零原子,但您可以轻松添加一个约束来禁止这种情况。这里是DCG的可能性。我想它相当干净
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].
这里的基本产品是list//1,它匹配任何确定长度的标记列表
注意:列表(A),列表(B),
,应避免A和B都未绑定。
如果中间有代币就可以了,比如在
列表(A),[和],列表(B),
谢谢,我会研究一下。我自己最终得到了一个DCG解决方案,而不是您的列表谓词,我创建了一个稍微不同的通配符谓词。你的看起来短一些,我会比较一下。