2011-11-23 78 views
2

我需要检查第二个列表中的每个元素是否具有比第一个列表中的相同元素多3倍的实例。我的函数一直返回false,我不知道我的东西是错的。PROLOG:检查第一个列表是否包含比第二个列表少3倍的元素

下面是代码:

fourth(_,[ ]). 
fourth(A,[HF|TF]) :- 
    intersection(A, HF, NewA), 
    intersection(TF, HF, NewB), 
    append(HF, NewB, NewT), 
    append(NewA, NewA, NewAA), 
    append(NewA, NewAA, NewAAA), 
    length(NewAAA) == length(NewT), 
    select(HF, TF, NewTF), 
    fourth(A, NewTF). 

例子:

?- fourth([1,2,3], [1,1,1]). 
true. 

?- fourth([1,2,3], [1,1,1,1]). 
false. 

?- fourth([1,2,3], [1,1]). 
false. 

?- fourth([1,2,2,3], [1,1,2,2,1,2,2,2,2]). 
true. 

回答

3

我会让自己select/3谓词:select(X,From,Left),然后对于每个elt的第一个列表我会叫它三次与第二个名单上的第一个参数相同,逐渐将它传递给我,最终Left3没有出现X三次出现; iand我会做第一个列表的每个elt。然后,如果我成功并最终得到一个空白列表,那意味着它从第一个列表中每次都精确到三次。

+1

请注意,如果您使用SWI-pl的**选择/ 3 **,它会失败的第四个([1,2,3],[1,1,1])。而如果您尊重OP规范,则不应该这样做。在使用** select/3 **之前使用** member/2 **知道当前的第一个列表元素是否在第二个列表中,但应该可以解决这个问题。 – m09

1

这是你的失败的原因码搭配建议:

fourth(_,[]). 
fourth(A,[HF|TF]) :- 
    intersection(A, HF, NewA), 
    intersection(TF, HF, NewB), 

这不是路口/ 3你想要使用,有两个原因:

1)它不仅过滤在A. HF

2)如果用一个元件称之为失败,所以至少可以使用[HF]代替HF的

相反,使用包括(=(HF),A,NewA)。有关更多信息,请参阅SWI-pl文档。

append(HF, NewB, NewT), 
    append(NewA, NewA, NewAA), 
    append(NewA, NewAA, NewAAA), 

使用追加/ 2比较好,尤其是对你的NewAAA名单。

length(NewAAA) == length(NewT), 

你不能比较这样的长度。首先,长度/ 1不存在 内置的swi-pl谓词。相反,直接比较列表或使用长度/ 2长度为 然后比较结果。

select(HF, TF, NewTF), 
    fourth(A, NewTF). 

只在TF中删除一次HT会导致算法失败。您需要 删除HT的所有出现在TF,与减/ 3例如...

如果你想有一个可行的解决方案尊重你原来的工作,我会添加它,所以随意问,但因为它被标记作业,我会让你第一个工作线索...

2

你的代码似乎不必要的复杂。它还包含使用HF而不是列表[HF]的错误。

那么你想实现什么逻辑?:

  1. 采取的下一个元素从第二个列表(不留尾巴)
  2. 检查,如果它在第一个列表,如果是,将其删除(否则失败)
  3. 删除两次以上从第二个列表

的尾部,这给:在我们的 “块世界”

fourth(_,[ ]). 
fourth(A,[HF|TF]) :- 
    once(select(HF, A, AR)), % using once/1 to avoid choicepoints 
    once(select(HF, TF, TF1)), 
    once(select(HF, TF1, TFR)), 
    fourth(AR, TFR). 
+2

这是作业,也许不明确的代码是不受欢迎的。你的回答遵循了威尔内斯已经提出的建议。 – CapelliC

+0

采取了点。虽然我总是觉得我从分析好的解决方案中学到的东西越来越多,而不是努力想出一个平庸的解决方案。不知道这些日子是如何完成的,但我会要求彻底解释推理,所以只是复制代码不会削减它。 – twinterer

0

%块 % %B3 %B4 B7 %B1 B5 B8 %B2 B6 B9 %==============

%块上堆叠 (B1,B2)。 (b3,b4)上的 。 (b4,b5)上的 。 (b5,b6)上的 。 (b7,b8)上的 。 (b8,b9)上的 。

%堆栈顺序 left(b2,b6)。 (b6,b9)。

%概括“above” above(Above,Below): - on(Above,Below)。上面(上面,下面)上面的 : - 上面(上面,AnyBlock),上面(AnyBlock,下面)。

%isLeft(X,Y)解析为真,如果X是留下的任何块Y的 %的嵌段isLeft/2只是调用leftOf/2后跟一个切口(!),以保证 %只有一个结果生成。例如:isleft(b1,b7)会产生错误,如果isleft(b2,b6)产生错误,则isleft(b4,b5)会产生错误。 %isleft(b9,b3)产生错误。 (X,Y): - leftOf(X,Y),!。 %显示左下方的实现。该实现将涉及少数情况(如上面的上述谓词),但可以仅使用提供左上和上述谓词的 %来完成。

相关问题