嗨我应该学习Prolog,我的老师要求我们创建一个谓词。我们被要求创建一个名为compose的谓词,其作用类似于zip,但可以采用两个不均匀长度的输入列表。如果一个比另一个大,它只是将较大列表的剩余多余元素附加到结果的末尾。 老师指定的行为是这样的:
?- compose([a,b,c],[x,y,z],L).
L = [a,x,b,y,c,z]
?- compose([a,b,c],[x,y],L).
L = [a,x,b,y,c]
?- compose(L1,L2,[a,b,c]).
L1 = [] L2 = [a,b,c] ;
L1 = [a] L2 = [b,c] ;
L1 = [a,c] L2 = [b];
L1 = [a,b,c] L2 = []
我的谓词到目前为止:
my_compose([], [], []).
my_compose(List1, [], R):-
append([], List1, R).
my_compose([], List2, R):-
append([], List2, R).
my_compose([Item1|Tail1], [Item2|Tail2], [Item1, Item2|R]):-
my_compose(Tail1, Tail2, R).
但我的输出有些不同:
?- my_compose([a,b,c], [x,y,z], L).
L = [a, x, b, y, c, z] ;
L = [a, x, b, y, c, z] ;
L = [a, x, b, y, c, z].
?- my_compose([a,b,c], [x,y], L).
L = [a, x, b, y, c] ;
false.
?- my_compose(L1, L2, [a,b,c]).
L1 = [a, b, c],
L2 = [] ;
L1 = [],
L2 = [a, b, c] ;
L1 = [a, c],
L2 = [b] ;
L1 = [a],
L2 = [b, c] ;
false.
如果有人能解释我在这里缺少的东西,我会深表感激吗?
编辑:这和shuffle之间的区别在于shuffle用于两个相同长度的列表。此外,这应该是向后查询。
答案 0 :(得分:0)
让我们来看看这一行:
my_compose([Item1|Tail1], [Item2|Tail2], [Item1, Item2|R]):-
my_compose(Tail1, Tail2, R).
您从两个列表中获取两个元素并混合它们。所以你的新名单就像
list1 = [1,2,3,4]
和list2 = [5,6,7,8]
并且您尝试创建看起来像这样的列表。
Result = [4,8,3,7,2,6,1,5]
。
然后你在这里调用append predicate
my_compose(List1, [], R):-
append([], List1, R).
my_compose([], List2, R):-
append([], List2, R).
你的R
没有指向List1,那么你如何期望实例化R(给你结果)。你应该这样写:
my_compose(List1, [], R):-
R = List1.
或者有一种简单的方法:
my_compose([], List2, List2).
注意您无法在空列表中调用追加,因此此谓词失败,意味着prolog没有找到任何成功的分支。
如果我们只从一个列表中选择一个元素,而不是这样:
my_compose([Item1|Tail1], List, [Item1|R]):-
my_compose(Tail1, List, R).
现在会发生什么?我的第一个列表将在一段时间后变空,我的第三个参数将是这样的[a,b,c|_someNumber]
someNumber表示变量。因此,当列表为空时,您可以定义另一个谓词:
my_compose([], List2, List2).
这表示如果我的第一个列表为空,则将我的第三个参数设置为等于第二个列表。
所以你看到你有类似[a,b,c|_someNumber]
的东西,someNumber作为参数传递,此时如果我说_omNumber = list2
那么我会得到一个这样的列表:([a,b,c,x,y,z]
所以你只需要这段代码:
my_compose([], List2, List2).
my_compose([Item1|Tail1], List, [Item1|R]):-
my_compose(Tail1, List, R).