Prolog Subag(x,y)测试被视为包的x是否是y的子包

Prolog Subag(x,y)测试被视为包的x是否是y的子包,prolog,Prolog,我目前正在研究一些prolog问题,其中一个是“subag(x,y)测试x,作为一个包,是否是y的subag”。我的代码根本不起作用,而且总是正确的。这是我的密码 delete(X,[],[]). delete(X,[X|T],T). delete(X,[H|T],[H|Result]):- delete(X,T,Result). subBag([],[]). subBag([],[H|T]). subBag([X|S],[H|T]):- member(X,[H|T]), d

我目前正在研究一些prolog问题,其中一个是“subag(x,y)测试x,作为一个包,是否是y的subag”。我的代码根本不起作用,而且总是正确的。这是我的密码

delete(X,[],[]).
delete(X,[X|T],T).
delete(X,[H|T],[H|Result]):-
   delete(X,T,Result).

subBag([],[]).
subBag([],[H|T]).
subBag([X|S],[H|T]):-
   member(X,[H|T]),
   delete(X,[H|T],Result),
   subBag(S,Result).

谢谢。

我不完全理解您的代码应该如何工作,但我认为在不必要的地方肯定有太多的拆分

也许这个谓词将帮助您解决问题

isSublist(Sublist,List) :-
    append([_,Sublist,_],List).

此谓词使用append/2内置谓词,

什么是子标记?我认为这意味着,子包装中的所有物品至少与包装袋中的物品数量相同。为了归纳地陈述它,让我们把它分成两种情况:一种情况是我有一个空列表。那是一个小背包吗?是,在任何列表中:

subbag([], Bag) :- is_list(Bag).
现在,归纳案例。让我们将子包分解为一个项目和子包的其余部分。如果该物品可以从包装袋中取出,其余部分构成包装袋剩余部分的子包,则我们有一个子包。像这样:

subbag([X|Subbag], Bag) :-
    select(X, Bag, RemainingBag),
    subbag(Subbag, RemainingBag).
这里的magic谓词是一个非常有用的实用程序,它允许您在一条语句中说
X
Bag
中,而包的其余部分在
RemainingBag
中。在Prolog中处理列表时,似乎总是出现这种情况。(请注意,在SWI Prolog文档中,名称旁边通常会有一个小橙色的
:-
图标,它将带您找到该谓词的源代码,以防愚蠢的教授要求您不要使用内置谓词。)


我想警告你,这个解决方案的效率不是很高,但我实际上认为这个问题的本质可能就是这样。您将从查询中获得的解决方案的数量(如
subag(X,[1,2,3,4,5])
)将会很大;我发现它本质上是一个集合的排列数,使用OEIS(序列)。

需要提示吗?可能会帮你解决这个问题。你的代码不起作用?给出你期望的和不起作用的具体案例。至少对于
subag([a],[a,b]),它是成功的。
如果我尝试了一个错误的情况,那么输出是正确的。例如subBag([1,1,2],[1,2])将给我真实的信息。我将归纳步骤更改为
subBag([X | S],[H | T]):-成员(X,[H | T]),删除(X,[H | T],[H | Result]),subBag(S,Result)。
它最终起作用。我们不允许使用内置函数,我认为subBag的定义不同于子列表/子集。谢谢,这很有帮助。@Pan没问题!始终尝试用基本案例/归纳案例分析来分解列表问题,这样你就会走上正确的轨道。对于任何递归数据结构也是如此。