1

嗨,我想编写一个名为 perfect_part 的函数,该函数将整数列表作为输入,如果可能,返回两个子列表,其总和恰好是原始列表中所有整数的总值的一半。例如,

?- perfect_part([6, 3, 2, 1], L, R).
L = [6],
R = [3, 2, 1] ;
false.

?- perfect_part([1, 2, 3, 4, 0], L, R).
L = [1, 4],
R = [2, 3, 0] ;
L = [2, 3],
R = [1, 4, 0] ; 

这是我的尝试:

listsum([], 0).
listsum([H|T], Total):-
    listsum(T, Sum1),
    Total is H + Sum1.

    subset([],L).
    subset([X|T],L):- member(X,L),subset(T,L).

perfect_part([], 0, 0).
perfect_part(Nums, Left, Right):-
    listsum(Nums, S),
    H is S / 2,
    subset(Left, Nums),
    subset(Right, Nums),
    listsum(Left, H),
    listsum(Right, H).

但是如果我运行它,我会收到错误消息:

错误:is/2:参数没有充分实例化

我该如何解决?我在解决这个问题的正确轨道上吗?

4

1 回答 1

1

The predicate subset/2 is missing, and it's an essential part to answer your question. Specifically, if sublists are contiguous, you can solve as easily as

perfect_part(X,L,R) :- append(L,R,X), listsum(L,S), listsum(R,S).

Then I would look for a more adequate replacement for append/3, like

partition([],[],[]).
partition([H|T],[H|L],R) :- partition(T,L,R).
partition([H|T],L,[H|R]) :- partition(T,L,R).

that leads to

perfect_part(X,L,R) :- partition(X,L,R), listsum(L,S), listsum(R,S).

edit Now, from subset/2 it's apparent the error cause: in base case, L is unbound.

Should be subset([],[])., but it doesn't terminate. I wonder how you get the error...

more edit To avoid duplicate solutions, I suggest to break the symmetry with

perfect_part(X,L,R) :- partition(X,L,R), L @=< R, listsum(L,S), listsum(R,S).
于 2014-03-20T08:21:46.857 回答