You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现按第一个列表元素个数复制第二个列表的Prolog谓词?

Fixing Your Prolog times/3 Predicate

Let's break down why your original code isn't working, then walk through a correct implementation that does exactly what you need.

What's Wrong With the Original Code?

Your current code has a key issue with variable binding and result accumulation:

times( [ ], _, [ ] ) :- !. 
times( [ _ | List1 ], List2, Result ) :- 
    append( [], List2, Result ),  % This binds Result directly to List2
    times( List1, List2, Result ).  % Now you're trying to re-bind Result in recursion

When you call append([], List2, Result), you're immediately setting Result equal to List2. Then, when you recurse, you pass the same Result variable—Prolog can't change its value, so the recursion just keeps reaffirming Result = List2 instead of building up the repeated list. That's why you never get the duplicated list you expect.

Correct Implementation Options

Option 1: Tail-Recursive with Accumulator (Efficient)

Tail recursion is better for performance in Prolog, as it avoids building up a stack of recursive calls. We'll use an accumulator to build our result step by step:

% Public predicate: start with empty accumulator
times(List1, List2, Result) :-
    times_acc(List1, List2, [], Result).

% Base case: when List1 is empty, return the accumulated result
times_acc([], _, Accumulator, Accumulator).

% Recursive case: append List2 to the accumulator, then recurse on the rest of List1
times_acc([_ | Rest], List2, Accumulator, Result) :-
    append(Accumulator, List2, NewAccumulator),
    times_acc(Rest, List2, NewAccumulator, Result).

Option 2: Simple Recursion (More Readable for Beginners)

If you prefer a more straightforward recursive approach without an accumulator, this works too:

% Base case: empty input list gives empty result
times([], _, []).

% Recursive case: first get the result of repeating List2 for the rest of List1,
% then prepend List2 to that sub-result
times([_ | Rest], List2, Result) :-
    times(Rest, List2, SubResult),
    append(List2, SubResult, Result).

Testing It Out

When you call times([x, x], [1, 5, 9, 8], Result), both implementations will correctly unify Result with [1, 5, 9, 8, 1, 5, 9, 8].

Let's trace the simple recursion version to see how it works:

  1. times([x, x], [1,5,9,8], R) calls times([x], [1,5,9,8], SubR)
  2. times([x], [1,5,9,8], SubR) calls times([], [1,5,9,8], SubSubR)
  3. times([], ..., SubSubR) unifies SubSubR with []
  4. Back to the second call: append([1,5,9,8], [], SubR) → SubR = [1,5,9,8]
  5. Back to the first call: append([1,5,9,8], [1,5,9,8], R) → R = [1,5,9,8,1,5,9,8]

内容的提问来源于stack exchange,提问作者adi pslr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:02:29