Prolog检查列表是否包含另一个列表元素的2倍

Prolog检查列表是否包含另一个列表元素的2倍,prolog,Prolog,所以任务并没有那么困难,但问题是,我不能用术语或数字比较或排序来完成这项工作。我也做了一个检查,确认两个列表包含相同的元素(因此可以忽略该部分),但我不知道如何具体检查问题。例如,如果我有这样一个例子:List1[1,2]和List2[1,2,1,2]它应该是真的,如果List2是[1,2,2]或[1,2,1,2,1]应该是假的。这里有一个基本的方法,不使用任何数字。它确实使用了dif/2(或者,使用\=),这是一种“术语比较”,但不是您所指的那种 check2times([H|T],[H2|T

所以任务并没有那么困难,但问题是,我不能用术语或数字比较或排序来完成这项工作。我也做了一个检查,确认两个列表包含相同的元素(因此可以忽略该部分),但我不知道如何具体检查问题。例如,如果我有这样一个例子:List1
[1,2]
和List2
[1,2,1,2]
它应该是真的,如果List2是
[1,2,2]
[1,2,1,2,1]
应该是假的。

这里有一个基本的方法,不使用任何数字。它确实使用了
dif/2
(或者,使用
\=
),这是一种“术语比较”,但不是您所指的那种

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2. 
首先,一个谓词,用于表示元素在列表中正好出现0次(换句话说,它不是列表的成员):

例如:

?- exactly0_list(x, [a, b, c]).
true ;
false.
但是:

在此基础上,一个谓词表示元素在列表中正好出现1次:

exactly1_list(X, [X | Ys]) :-
    exactly0_list(X, Ys).
exactly1_list(X, [Y | Ys]) :-
    dif(X, Y),
    exactly1_list(X, Ys).
看看这看起来有多相似。其行为如下:

?- exactly1_list(b, [a, b, c]).
true ;
false.

?- exactly1_list(b, [a, b, c, b]).
false.
?- exactly2_list(b, [a, b, c, b]).
true ;
false.

?- exactly2_list(b, [a, b, c, b, b]).
false.
如果您看到一个模式正在出现,请按照相同的行实现谓词
2\u list/2
。它的行为应该是这样的:

?- exactly1_list(b, [a, b, c]).
true ;
false.

?- exactly1_list(b, [a, b, c, b]).
false.
?- exactly2_list(b, [a, b, c, b]).
true ;
false.

?- exactly2_list(b, [a, b, c, b, b]).
false.

然后用它对照第二个列表检查第一个列表中的每个元素。

这里有一个基本方法,不使用任何数字。它确实使用了
dif/2
(或者,使用
\=
),这是一种“术语比较”,但不是您所指的那种

首先,一个谓词,用于表示元素在列表中正好出现0次(换句话说,它不是列表的成员):

例如:

?- exactly0_list(x, [a, b, c]).
true ;
false.
但是:

在此基础上,一个谓词表示元素在列表中正好出现1次:

exactly1_list(X, [X | Ys]) :-
    exactly0_list(X, Ys).
exactly1_list(X, [Y | Ys]) :-
    dif(X, Y),
    exactly1_list(X, Ys).
看看这看起来有多相似。其行为如下:

?- exactly1_list(b, [a, b, c]).
true ;
false.

?- exactly1_list(b, [a, b, c, b]).
false.
?- exactly2_list(b, [a, b, c, b]).
true ;
false.

?- exactly2_list(b, [a, b, c, b, b]).
false.
如果您看到一个模式正在出现,请按照相同的行实现谓词
2\u list/2
。它的行为应该是这样的:

?- exactly1_list(b, [a, b, c]).
true ;
false.

?- exactly1_list(b, [a, b, c, b]).
false.
?- exactly2_list(b, [a, b, c, b]).
true ;
false.

?- exactly2_list(b, [a, b, c, b, b]).
false.

然后用它对照第二个列表检查第一个列表中的每个元素。

我的方法是“列表1[1,2]和列表2[1,2,1,2],如果列表2是[1,2,2]或[1,2,1,2,1]应该是假的,则应该是真的。”

1。check2times谓词比较两个列表,然后调用谓词check。check的工作是比较并给出列表中出现的对的总计数作为列表[1,1]。然后使用sum谓词对列表求和(例如[1,1]=2)。然后简单地检查sum=2是否应该返回true,否则将返回false

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2. 
2.检查谓词

check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).
sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
3。和谓词

check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).
sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
将所有内容放在一起:

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2.    
check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).

sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
?-check2times([1,2],[1,2,1,2]).
true
false
check2times([1,2],[1,2,1]).
false
?-check2times([2,2],[2,2,2,2]).
true
false
?-check2times([2,2],[2,2,2,2,2,2]).
false
?-check2times([2,2],[2,4,3,5,2,2,3,6,5,3,2,2]).
true
false
?-check2times([b,b],[b,b,a,d,f,g,w,q,b,b,h,y]).
true
false
?-check2times([b,b],[b,b,5,6,f,g,1,2,b,b,h,y]).
true
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4,1,2,3,4]).
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4]).
true
false
示例:

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2.    
check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).

sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
?-check2times([1,2],[1,2,1,2]).
true
false
check2times([1,2],[1,2,1]).
false
?-check2times([2,2],[2,2,2,2]).
true
false
?-check2times([2,2],[2,2,2,2,2,2]).
false
?-check2times([2,2],[2,4,3,5,2,2,3,6,5,3,2,2]).
true
false
?-check2times([b,b],[b,b,a,d,f,g,w,q,b,b,h,y]).
true
false
?-check2times([b,b],[b,b,5,6,f,g,1,2,b,b,h,y]).
true
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4,1,2,3,4]).
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4]).
true
false

我的方法是“列表1[1,2]和列表2[1,2,1,2],如果列表2是[1,2,2]或[1,2,1,2,1]应该是假的,那么它应该是真的。”

1。check2times谓词比较两个列表,然后调用谓词check。check的工作是比较并给出列表中出现的对的总计数作为列表[1,1]。然后使用sum谓词对列表求和(例如[1,1]=2)。然后简单地检查sum=2是否应该返回true,否则将返回false

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2. 
2.检查谓词

check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).
sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
3。和谓词

check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).
sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
将所有内容放在一起:

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2.    
check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).

sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
?-check2times([1,2],[1,2,1,2]).
true
false
check2times([1,2],[1,2,1]).
false
?-check2times([2,2],[2,2,2,2]).
true
false
?-check2times([2,2],[2,2,2,2,2,2]).
false
?-check2times([2,2],[2,4,3,5,2,2,3,6,5,3,2,2]).
true
false
?-check2times([b,b],[b,b,a,d,f,g,w,q,b,b,h,y]).
true
false
?-check2times([b,b],[b,b,5,6,f,g,1,2,b,b,h,y]).
true
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4,1,2,3,4]).
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4]).
true
false
示例:

check2times([H|T],[H2|T2]):-
    check([H|T],[H2|T2],N),
    sum(N,S),
    S=2.    
check(_,[],[]).
check([A,B|T],[H1,H2|L],[N|R]):-
    [A,B]=[H1,H2],
    N is 1+0,
    check([A,B|T],L,R).
check([A,B|T],[H1,H2|L],N):-
     [A,B]\=[H1,H2],
    check([A,B|T],L,N).

sum([],0).
sum([H|T],S):-
    sum(T,S1),
    S is S1+H.
?-check2times([1,2],[1,2,1,2]).
true
false
check2times([1,2],[1,2,1]).
false
?-check2times([2,2],[2,2,2,2]).
true
false
?-check2times([2,2],[2,2,2,2,2,2]).
false
?-check2times([2,2],[2,4,3,5,2,2,3,6,5,3,2,2]).
true
false
?-check2times([b,b],[b,b,a,d,f,g,w,q,b,b,h,y]).
true
false
?-check2times([b,b],[b,b,5,6,f,g,1,2,b,b,h,y]).
true
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4,1,2,3,4]).
false
?-check2times([1,2,3,4],[1,2,3,4,1,2,3,4]).
true
false

为什么不把较小的列表复制到一个新列表中,每个项目重复两次,然后生成该列表的排列,如果其中一个与另一个列表匹配,则为真?如果找到第一个元素,则使用递归,然后对剩余的列表执行member。为什么不把较小的列表复制两次,将每个项目复制到一个新列表中两次,然后生成该列表的排列,如果其中一个与另一个列表匹配,则为true?如果找到了第一个元素,则使用递归,然后对剩余列表执行member。但这对于例如
[1,1]
[1,1,1,1]
,但是它应该但是这不会,例如对于
[1,1]
[1,1,1]
,但是它应该