2009-12-09 30 views
3

我需要一些帮助,我正在尝试创建一个例程。我需要做一个常规的,将是这个样子:Prolog差异例程

difference([(a,b),(a,c),(b,c),(d,e)],[(a,_)],X). 

X = [(b,c),(d,e)]. 

我真的需要在这一个帮助..

我写了一个方法,到目前为止,可以删除第一次出现,它认为。但是我需要它删除所有的事件。以下是我迄今为止...

memberOf(A, [A|_]). 
memberOf(A, [_|B]) :- 
    memberOf(A, B). 

mapdiff([], _, []) :- !. 
mapdiff([A|C], B, D) :- 
     memberOf(A, B), !, 
     mapdiff(C, B, D). 
mapdiff([A|B], C, [A|D]) :- 
     mapdiff(B, C, D). 

我采取这种代码列表(减去)。

我不完全明白它的作用,但我知道它几乎是我想要的。我没有使用减法,因为我的最终代码必须与WIN-Prolog兼容......我正在SWI Prolog上测试它。

+0

您的代码适用于我(在SWI-Prolog和GNU-Prolog中)。我不知道WIN-Prolog,所以我不能帮你。 – Stephan202 2009-12-09 18:52:25

+1

它的工作原理,但它并没有消除所有的A的发生。它只消除了第一个。 – SteveW 2009-12-09 18:55:00

+1

你是对的。不知何故,我看起来错了(?)。我认为问题在于成员检查执行统一,结果在第一次测试后'(a,_)'成为'(a,b)',这将不再与'(a,c)'匹配。我正在考虑一个不错的解决方案... – Stephan202 2009-12-09 19:06:43

回答

2

我不确定,但是像这样的东西可以工作。您可以使用findall发现不能与模式统一所有元素:

?- findall(X, (member(X, [(a,b),(b,c),(a,c)]), X \= (a,_)), Res). 

得到的答复

Res = [ (b, c) ] 

所以

removeAll(Pattern, List, Result) :- 
    findall(ZZ109, (member(ZZ109, List), ZZ109 \= Pattern), Result). 

应该工作,假设ZZ109 ISN”在Pattern中有一个变量(不幸的是,我不知道如何获得一个新的变量,WIN-Prolog中可能有一个不可移植的变量)。然后difference可以递归定义:

difference(List, [], List). 
difference(List, [Pattern|Patterns], Result) :- 
    removeAll(Pattern, List, Result1), 
    difference(Result1, Patterns, Result). 
+2

ZZ109是一个新鲜的变量。在内部,Prolog更改变量的名称。如果您在同一个子句中明确使用ZZ109,它只会是相同的变量。即:模式中的ZZ109可能在内部重命名为_123,而差异子句中的ZZ109将重命名为_314。没有什么可担心的..虽然好的解决方案。 – neXus 2010-11-11 16:44:37

2

您的代码可以轻松地修改以使其工作,以便memberOF谓词只检查到存在可以没有统一列表中的某个元素实际上统一它。在SWI序言这是可以做到这样:

memberOf(A, [B|_]) :- unifiable(A,B,_). 

但我不熟悉的WIN-PROLOG所以不知道它是否有一个谓语或操作员只测试是否论据是可以统一的。

3

棘手的一个! 不起眼的咖啡有正确的想法。这是一个使用双重否定的奇特解决方案:

difference([], _, []). 
difference([E|Es], DL, Res) :- 
    \+ \+ member(E, DL), !, 
    difference(Es, DL, Res). 
difference([E|Es], DL, [E|Res]) :- 
    difference(Es, DL, Res). 

适用于SWI-PROLOG。说明:

第1条:基本情况。没有任何差异!

第2条:如果E是在差异列表DL的member/2子目标的计算结果为true,但我们不希望接受member/2使得目前的变量之间的条件任一列表绑定,因为我们想例如,术语(a,_)中的变量可以在其他术语中重复使用,而不受第一种解决方案的约束。因此,根据需要,第一个\+删除由成功评估member/2创建的可变绑定,第二个\+将评估状态反转为true。剪切发生在检查之后,不包括第三个子句,并丢弃可一致的元素。

第3条:让任何元素在两个列表中都不可统一。