If I understood correctly, the first two declarations in your last attempt would mean that a list with 1 element is a correct subset of an empty list (false), and that an empty list is a proper subset of a list with one element (true); the first one should be problematic, because proper([1], []) will succeed, as well as proper([],[1]) , but the correct relation of the subset is asymmetric.
I believe that the reason your second attempt does not filter out identical subsets is because you do not have an declaration that requires A to be less than B.
Here are some possible solutions that I came up with. I use smaller_set/2 couple of times for more clarity and clarity.
smaller_set(A, B) :- length(A, LA), length(B, LB), LA < LB.
def_proper_subset/2 tries to capture the standard definition of a subset.
def_proper_subset(A, B) :- smaller_set(A, B), % if A < B then there some _e in B that isn't in A. forall(member(_e, A), member(_e, B)).
An example with a recursive definition, based on the removal of each corresponding element A and B. It ensures that A <B only with success if A runs through the elements to B.
rec_proper_subset1([], [_|_]). rec_proper_subset1([_e|A], B) :- select(_e, B, C), % C is B with _e removed. Only true if _e is in B. rec_proper_subset1(A, C).
In this case, the auxiliary attribute predicate is used to verify ownership as soon as the main predicate has already assured that A <B.
rec_proper_subset2(A, B) :- smaller_set(A, B), rec_proper_subset2_(A, B). rec_proper_subset2_([], _). rec_proper_subset2_([_e|A], B) :- member(_e, B), rec_proper_subset2_(A, B).
Edit:
- You need to use
list_to_set/2 , sort/2 or something similar if you want to be sure that there are no duplicate elements in your lists. But such solutions will also work to find helper lists. - I think
def_proper_subset/2 is a kind of crappy solution, because it will only work to verify that A is a subset of B, but cannot generate a subset of B in A. The other two can be thought of.
(I screwed it and forgot to include the definition of land for rec_proper_subset2/2 , but now I fixed it).