List 通过连接原子统一不同长度的列表

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

考虑以下列表:

[我的名字是,杰克,鲍尔]

我想将其统一为以下模式:

[我的,名字,是,名字]

因此,变量名最后的值为“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中如何处理这个问题?

您需要一个自定义的统一算法,例如:

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解决方案,而不是您的列表谓词,我创建了一个稍微不同的通配符谓词。你的看起来短一些,我会比较一下。