Prolog 通过另一个列表复制列表';s项目数量

Prolog 通过另一个列表复制列表';s项目数量,prolog,Prolog,我试图做到这一点: times([x, x], [1, 5, 9, 8], Result). 第二个列表按第一个列表中的元素数复制 结果是:[1,5,9,8,1,5,9,8] 我已尝试过此方法,但无法正常工作: times( [ ], _, [ ] ) :- !. times( [ _ | List1 ], List2, Result ) :- append( [], List2, Result ),

我试图做到这一点:

times([x, x], [1, 5, 9, 8], Result).
第二个列表按第一个列表中的元素数复制

结果是:
[1,5,9,8,1,5,9,8]

我已尝试过此方法,但无法正常工作:

times( [ ], _, [ ] ) :- !.
times( [ _ | List1 ], List2, Result ) :-    append( [], List2, Result ),
                                            times( List1, List2, Result ).

提前谢谢

首先,基本情况下不需要切割。它不必要地删减了解决方案搜索:

replicate([], _, []).   % The empty list is the result of replicating any list by []
然后您的递归规则,
replicate([|List1],List2,Result)
似乎有一个合理的格式/头。但你的身体有逻辑问题。如果你要描述逻辑,那就没有意义了。特别是,您在两个不同的位置使用
Result
表示两种不同的含义,这将导致意外的失败。谓词只是需要从逻辑上考虑它的含义:

Result
[\u124; List1]
List2
的复制,如果
SubResult
List1
List2
的复制,
Result
是将
SubResult
附加到
List2
的结果

注意此处使用的“子结果”(
subresult
)与主结果(
result
)不同。这些变量必须是不同的,这一点很重要

如果将其作为序言编写,则会得到:

replicate([_|List1], List2, Result) :-
    replicate(List1, List2, SubResult),
    append(List2, SubResult, Result).
我没有测试这个,但这个基本上可以。作为Prolog学习过程的一部分,您应该自己尝试并解决任何遗留问题。我也没有考虑是否有一个更有效的方法来解决整个问题,但我只是用当前的方法来解决你的问题。
另一种方法是使用
maplist/2
append/2
。您可以使用
maplist/3
获取列表列表,然后使用
append/2
获取结果:

replicate(List1, List2, Result) :-
    length(List1, Len),
    length(R1, Len),
    maplist(=(List2), R1),
    append(R1, Result).

稍加考虑,可以使用简单的递归列表处理来解决这个问题。在本例中,您将递归地将结果的头部与第二个列表中每个元素的头部统一起来,然后对第一个列表中的每个元素继续此过程

replicate(Rep, List, Res) :-
    replicate(Rep, List, List, Res).

replicate([], _, _, []).
replicate([R|Rs], List, [X|Xs], [X|Res]) :-
    replicate([R|Rs], List, Xs, Res).
replicate([R|Rs], List, [], Res) :-
    replicate(Rs, List, List, Res).

首先,你不需要在基本情况下削减。它不必要地删减了解决方案搜索:

replicate([], _, []).   % The empty list is the result of replicating any list by []
然后您的递归规则,
replicate([|List1],List2,Result)
似乎有一个合理的格式/头。但你的身体有逻辑问题。如果你要描述逻辑,那就没有意义了。特别是,您在两个不同的位置使用
Result
表示两种不同的含义,这将导致意外的失败。谓词只是需要从逻辑上考虑它的含义:

Result
[\u124; List1]
List2
的复制,如果
SubResult
List1
List2
的复制,
Result
是将
SubResult
附加到
List2
的结果

注意此处使用的“子结果”(
subresult
)与主结果(
result
)不同。这些变量必须是不同的,这一点很重要

如果将其作为序言编写,则会得到:

replicate([_|List1], List2, Result) :-
    replicate(List1, List2, SubResult),
    append(List2, SubResult, Result).
我没有测试这个,但这个基本上可以。作为Prolog学习过程的一部分,您应该自己尝试并解决任何遗留问题。我也没有考虑是否有一个更有效的方法来解决整个问题,但我只是用当前的方法来解决你的问题。
另一种方法是使用
maplist/2
append/2
。您可以使用
maplist/3
获取列表列表,然后使用
append/2
获取结果:

replicate(List1, List2, Result) :-
    length(List1, Len),
    length(R1, Len),
    maplist(=(List2), R1),
    append(R1, Result).

稍加考虑,可以使用简单的递归列表处理来解决这个问题。在本例中,您将递归地将结果的头部与第二个列表中每个元素的头部统一起来,然后对第一个列表中的每个元素继续此过程

replicate(Rep, List, Res) :-
    replicate(Rep, List, List, Res).

replicate([], _, _, []).
replicate([R|Rs], List, [X|Xs], [X|Res]) :-
    replicate([R|Rs], List, Xs, Res).
replicate([R|Rs], List, [], Res) :-
    replicate(Rs, List, List, Res).

我们可以用第二个列表替换第一个元素中的每个元素,然后调用
append/2
(SWI Prolog有一个):


我们可以用第二个列表替换第一个元素中的每个元素,然后调用
append/2
(SWI Prolog有一个):


第二个列表乘以第一个列表中的元素数。你的意思是说复制不是成倍的?使用一个包含所有相同元素的示例并不能最好地说明谓词需要做什么。重复,对不起。
时间([a,3],[d,e,7])的预期结果是什么。
?[d,e,7,d,e,7]。@<代码>时间([],u,u)。我只是把它放在那里来停止递归。规则,
时间([],u,u)。
说空列表乘以任何东西都是不符合逻辑的东西,是吗?例如,
次([],[a,b],foo(27))。
成功。什么样的结果会导致成功?第二个列表乘以第一个列表中的元素数。你的意思是说复制不是成倍的?使用一个包含所有相同元素的示例并不能最好地说明谓词需要做什么。重复,对不起。
时间([a,3],[d,e,7])的预期结果是什么。
?[d,e,7,d,e,7]。@<代码>时间([],u,u)。我只是把它放在那里来停止递归。规则,
时间([],u,u)。
说空列表乘以任何东西都是不符合逻辑的东西,是吗?例如,
次([],[a,b],foo(27))。
成功。什么样的结果会导致成功?是的,比我的
append/2
hack好得多。@潜伏者为什么它是相同的
append/2
hack,:)我只是在
长度上“剪短”了。我喜欢这个
[A,A,…,A],A=x
技巧,但是这里
A=
可以融合到列表创建本身中。哈,你在技术上是正确的。我应该说
length/2
hack。当我写它时,我不喜欢那样使用
length/2
。。。只是觉得恶心。啊,是的。事实上,这正是我们所需要的