检查变量列表是不是与包含字母的列表一致

Posted

技术标签:

【中文标题】检查变量列表是不是与包含字母的列表一致【英文标题】:Checking if a list of variables is unifiable with a list of lists containing letters检查变量列表是否与包含字母的列表一致 【发布时间】:2020-08-08 09:14:48 【问题描述】:

我有这个谓词spaces_uni(Spc,LstWords),Spc 是一个变量列表,如[X,Y,Z][a,Y,Z],LstWords 是一个单词列表,如[[o,r,a,n,g,e],[a,p,p,l,e],[b,a,n,a,n,a]]

这个谓词的目的是检查LstWords中是否有任何单词可以与给定的Spc统一。

例子:

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], spaces_uni(Space,Words).
true.

那么为什么输出是正确的,简单的,因为戏剧这个词与 [d,A,B,C,D] 统一变成了 [d,r,a,m,a]。问题是我的程序反而返回 false,我不明白为什么。

程序:

spaces_uni(E,[P|R]) :-
                         length(E,CE),
                         length(P,CP),
                         CE \== CP,!,
                         spaces_uni(E,R).

spaces_uni(E,[P|R]) :-
                           length(E,CE),
                           length(P,CP),
                           CE == CP,!,
                           P \= E,
                           spaces_uni(E,R).


spaces_uni(E,[P|_]) :-
                         length(E,CE),
                         length(P,CP),
                         CE == CP,
                         /(P = E),!,
                         true.

真的很感激任何帮助。

【问题讨论】:

【参考方案1】:

您使用的是什么 Prolog 实现,您从哪里得到目标 /(P = E)

Prolog 的统一已经很好地处理了列表统一:

?- [d, A, B, C, D] = [d, r, a, m, a].
A = r,
B = D, D = a,
C = m.

?- [x, A, B, C, D] = [d, r, a, m, a].
false.

因此,您需要做的就是编写一个谓词,如果列表与列表列表中的一个元素统一,则该谓词会成功。

类似:

word_words(Word, [Word | _Words]).
word_words(Word, [_Word | Words]) :-
    word_words(Word, Words).

像这样工作:

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], word_words(Space, Words).
Words = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, r, a, m, a], [m, a, e], [m, a, n|...], [s, e|...], [s|...]],
Space = [d, r, a, m, a],
A = r,
B = D, D = a,
C = m ;
false.

但我们甚至不需要定义自己的word_words/2 谓词。它不做任何特定于单词的事情,如果我们重命名一些东西,它可能看起来更熟悉:

member_list(X, [X | _List]).
member_list(X, [_Y | List]) :-
    member_list(X, List).

这只是一个表示列表成员资格的谓词。所以我们根本不需要编写任何谓词定义,我们可以使用您的 Prolog 实现可能附带的现有成员谓词:

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], member(Space, Words).
Words = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, r, a, m, a], [m, a, e], [m, a, n|...], [s, e|...], [s|...]],
Space = [d, r, a, m, a],
A = r,
B = D, D = a,
C = m ;
false.

?- Words = [[a,m,e,n,o],[a,t,o],[d,a,o],[d,r,a,m,a],[m,a,e],[m,a,n,d,e],[s,e,d,e],[s,o,a,r]], Space = [d,A,B,C,D], memberchk(Space, Words).
Words = [[a, m, e, n, o], [a, t, o], [d, a, o], [d, r, a, m, a], [m, a, e], [m, a, n|...], [s, e|...], [s|...]],
Space = [d, r, a, m, a],
A = r,
B = D, D = a,
C = m.

【讨论】:

以上是关于检查变量列表是不是与包含字母的列表一致的主要内容,如果未能解决你的问题,请参考以下文章

检查列表中与变量列表一致的所有单词

Python检查列表项是不是(不)包含任何其他列表项

检查列表是不是包含与某些东西不同的元素[重复]

检查元素是不是在列表中(包含)

Python - 检查一个字母是不是在列表中

根据值列表检查变量是不是相等