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).