Prolog差分程序

Prolog差分程序,prolog,logic,Prolog,Logic,我需要一些关于我正在尝试创建的例程的帮助。我需要做一个像这样的例行公事: 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

我需要一些关于我正在尝试创建的例程的帮助。我需要做一个像这样的例行公事:

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上测试它。

我不确定,但类似的东西可以工作。您可以使用
findall
查找无法与模式统一的所有元素:

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

Res = [ (b, c) ]
所以

假设
ZZ109
不是
模式中的变量(不幸的是,我不知道如何获取新变量。WIN Prolog中可能有一个不可移植的变量)。然后可以递归定义
差异

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

您的代码可以很容易地修改以工作,方法是使
memberOF
谓词只检查列表中是否有可以统一的元素,而不必实际统一它。在SWI Prolog中,可以通过以下方式完成:

memberOf(A, [B|_]) :- unifiable(A,B,_).
但是我不熟悉WIN PRolog,所以不知道它是否有一个谓词或运算符,它只测试参数是否可以统一。

棘手的一个!简陋的咖啡有正确的想法。下面是一个使用双重否定的奇特解决方案:

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,)
中的变量能够跨其他术语重用,并且不受第一个解决方案的约束。因此,第一个
\+
删除成功评估
成员/2
所创建的变量绑定,第二个
\+
根据需要将评估状态反转为
true
。切割发生在检查之后,不包括第3条,并丢弃统一元素


第3条:在两个列表中保留任何不统一的元素。

您的代码适用于我(在SWI Prolog和GNU Prolog中)。我不知道WIN Prolog,所以我不能帮你。好吧,它有效,但它不能消除A的所有发生。它只删除第一个。你是对的。不知怎的,我看起来不对劲。我认为问题在于成员检查执行统一,结果在第一次测试后
(a,)
变成
(a,b)
,这将不再与
(a,c)
匹配。我在考虑一个很好的解决方案…不,对不起。我希望一些更熟练的Prolog用户可以帮助您。(我应该花时间写论文:)ZZ109是一个新的变量。在内部,Prolog更改变量的名称。只有在同一子句中显式使用ZZ109时,它才会是相同的变量。也就是说:模式中的ZZ109可能在内部重命名为_123,而差异子句中的ZZ109将重命名为_314。没什么好担心的。。好的解决方案。
difference([], _, []).
difference([E|Es], DL, Res) :-
    \+ \+ member(E, DL), !,
    difference(Es, DL, Res).
difference([E|Es], DL, [E|Res]) :-
    difference(Es, DL, Res).