你没有得到解决方案,因为ord_subset/2
仅谓词checks如果一个列表是另一个列表的子集;它不生成子集。
这是定义谓词的一种简单方法,该谓词可以完成您所追求的任务:
subset_set([], _).
subset_set([X|Xs], S) :-
append(_, [X|S1], S),
subset_set(Xs, S1).
这假设这些是“ordsets”,即没有重复的排序列表。
您会注意到该子集恰好也是一个子序列。我们可以这样写:
subset_set(Sub, Set) :-
% precondition( ground(Set) ),
% precondition( is_list(Set) ),
% precondition( sort(Set, Set) ),
subseq_list(Sub, Set).
subseq_list([], []).
subseq_list([H|T], L) :-
append(_, [H|L1], L),
subseq_list(T, L1).
无论使用哪种定义,您都会得到:
?- length(Sub, 3), subset_set(Sub, [1,2,3,4]).
Sub = [1, 2, 3] ;
Sub = [1, 2, 4] ;
Sub = [1, 3, 4] ;
Sub = [2, 3, 4] ;
false.
您甚至可以在示例查询中切换两个子目标的顺序,但这可能是更好的编写方式。
然而,第二个论点must be地面;如果不是:
?- subset_set([A,B], [a,B]), B = a.
A = B, B = a ; Not a real set, is it?
false.