在序言中拆分列表,生成两个单独的列表

Split list in prolog, produce two separate lists

问题:

Define a predicate split/4 which, when provided with a list L and integer N returns two lists, A and B, where A contains the items in L that are greater than or equal to N and B contains the items that are lower than N.

具有预期结果的示例查询:

?- split([1, 5, 2, 3, 4], 3, A, B).
A = [5, 3, 4],
B = [1, 2].

我的代码:

spit([], 0, [], []).
split([I|Is], N, [A|As], [_B|Bs]):-
    I >= N,
    A is I,
    split(Is, N, As, Bs).
split([I|Is], N, [_A|As], [B|Bs]):-
    I < N,
    B is I,
    split(Is, N, As, Bs).

我的代码没有按要求生成 AB,而是简单地 returns false。我不确定为什么。

接近更正,但有些小错误。

一行一行:

一)

spit([], 0, [], []).

打字错误:spi vs split

规则说"the split of an empty list by 0 are two empty lists",是的,但是限制太多,改成"the split of empty list is two empty list, no matter the number":

split([], _, [], []).

b)

split([I|Is], N, [A|As], [_B|Bs]):-
    I >= N,
    A is I,
    split(Is, N, As, Bs).

"B" 保持未定义,即使您将其作为 _B 启动以抑制警告。将其更改为:

split([I|Is], N, [I|As], Bs ):-
    I >= N,
    split(Is, N, As, Bs).

c)

split([I|Is], N, [_A|As], [B|Bs]):-
    I < N,
    B is I,
    split(Is, N, As, Bs).

同上。

我认为这是作业,因为使用 SWI-Prolog,您有 partition/4

partition(:Pred, +List, ?Included, ?Excluded) [det]

Filter elements of List according to Pred.
True if Included contains all elements for which call(Pred, X) succeeds and Excluded contains the remaining elements.

split(L, N, A, B) :-
    partition( =<(N), L, A, B).

作为 partition/4 的替代方法,使用 tpartition/4 together with (#=<)/3,像这样:

?- tpartition(#=<(3),[1,5,2,3,4],As,Bs).
As = [5,3,4], Bs = [1,2].

感谢(#=<)/3,您可以 运行 更一般的查询!

详情请看my answer相关问题 “Splitting a list of integers into a list of positive integers and a list of negative integers”。