I am trying to create a Prolog predicate where, given a list, it is seen whether or not the list can be split into two lists that sum to the same amount.
I have a working list sum predicate, so I am using that within my partitioning predicate. I first tried to code the predicate to see if the first element of the list equals the sum of the rest of the list ([2,1,1]). This is what I have for that situation.
partitionable([X|Y]) :-
sum([X],SUM),
sum([Y],SUM2),
SUM = SUM2.
However, I am getting this error message:
ERROR: is/2: Arithmetic: `[]/0' is not a function.
I would like to get this piece working before I delve into the recursion for the rest of the list, though I am confused on what this message is saying, since I have not written a '[]/0' function
. Any help is appreciated.
It keeps getting better!
To non-deterministically partition lists, we don't need to implement a recursive auxiliary predicate like
list_subseq_subseq/3
if we employ the right meta-predicate/predicate combination!In this answer, we use
tpartition/4
as the meta-predicate and the "reified wild-card" predicate(*)/2
as the predicate passed totpartition/4
.(*)/2
can be defined like this:Let's put
tpartition/4
to use with(*)/2
and the clpfd constraints(#=)/2
andsum/3
:I would also offer another solution for the partition problem. helper predicate helps to cut the list two list. For example [1,2,3] can be cutted down:
[1,2] (left side) and [3](right side) or
[3] (left side) and [1,2] (right side).
Output is :
To partition a list into two non-overlapping subsequences, we use
list_subseq_subseq/3
:For performing integer arithmetics, we use clpfd:
Let's put it all together! In the following sample query we partition the list
[1,2,3,4,5,6,7]
:I believe that passing X as [X] is required, since X is just the element (the number 2 in your example). Y on the other hand is a list in itself an should not be put in another list. Here is the modified version:
partitionable([2,1,1])
returns true in my case.Edit: Since you do not use
is/2
this may be an error in thesum
predicate.On another note: As I understand your question you do not require a solution for
partitionable
but the error message you received. Nonetheless here is my take on implementing it (possibly spoiler ahead):Maybe I'm underthinking this, but...
If by "partition the list", you mean "cut the list in two, preserving order, rather than creating various permutations of the list),it doesn't seem like the solution should be any more complex than something like this:
If you want to avoid using built-ins, you could do something like this, which has the added benefits of elegance whilst minimizing list traversals: