List 序言:在两个列表之间匹配特定列表中的元素

List 序言:在两个列表之间匹配特定列表中的元素,list,prolog,pattern-matching,match,List,Prolog,Pattern Matching,Match,如果一个列表中的任何数字与另一个列表中的任何数字匹配,我已经有了匹配的代码。但是,我需要修改我的递归,这样如果在两个列表的相同位置发现相同的数字,它就会返回false 例如: [5,3,4,6,2]与[3,1,2,2,7]兼容;而[1,3,4,9,2]与[4,5,2,9,8]不兼容,因为两个列表的第4位都有一个9 以下是我目前掌握的代码: common_elements([], L) :- fail. common_elements([H|T], L) :- memberchk(

如果一个列表中的任何数字与另一个列表中的任何数字匹配,我已经有了匹配的代码。但是,我需要修改我的递归,这样如果在两个列表的相同位置发现相同的数字,它就会返回false

例如:

[5,3,4,6,2]
[3,1,2,2,7]
兼容;而
[1,3,4,9,2]
[4,5,2,9,8]
不兼容,因为两个列表的第4位都有一个9

以下是我目前掌握的代码:

common_elements([], L) :-
    fail.
common_elements([H|T], L) :-
    memberchk(H, L), !.
common_elements([H|T], L) :-
    common_elements(T, L).
当前代码的SWI Prolog示例输入和输出:

?- common_elements([1,2,3,4],[6,7,8,9]).
false.

?- common_elements([1,2,3,6],[6,7,8,9]).
true.
与(几乎)所有使用列表处理的谓词一样,您可以将谓词拆分为两种类型的子句:

  • 基本子句:在许多情况下,这些列表处理空列表。例如:

    compatible([],_).
    compatible(_,[]).
    
  • 归纳从句:在这种情况下,两个列表都不是空的。在这种情况下,您必须比较两个列表的标题。如果不相等,则进行递归调用:

    compatible([HA|TA],[HB|TB]) :-
        HA \= HB,
        compatible(TA,TB).
    
    在递归调用中,只需使用两个列表的尾部

现在合并这两个条款:

compatible([],_).
compatible(_,[]).
compatible([HA|TA],[HB|TB]) :-
    HA \= HB,
    compatible(TA,TB).
您可以使其更有效(并通过使用切割使其原子化):

演示(
swipl

?- compatible([5,3,4,6,2],[3,1,2,2,7]).
true.

?- compatible([1,3,4,9,2],[4,5,2,9,8]).
false.

两个列表是否必须具有相同的长度?列表项是否必须是数字?如果列表具有相同的长度,您可以执行:
maplist(dif,L1,L2)
?- compatible([5,3,4,6,2],[3,1,2,2,7]).
true.

?- compatible([1,3,4,9,2],[4,5,2,9,8]).
false.