Prolog 成员谓词

2023-12-07

我需要编写一个 Prolog 谓词,以避免手头列表中多次出现的项目出现冗余答案,如以下示例查询所示:

?- member(a, [a, b, a]).
true
?- member(X, [a, b, a]).
X = a ;
X = b ;
false.
?- member(X, [a, b, a, c, a, d, b]).
X = a ;
X = b ;
X = c ;
X = d ;
false.

我知道以下内容将输出所有内容,无论重复如何:

member(X, [X|_]).
member(X, [_|T]) :- member(X, T).

比较这两个条款,是否存在两者都适用的情况?

member(X, [X|_T]).
member(X, [_Y| T]) :- member(X, T).

只需将两个子句的标题相互比较即可。或者,让 Prolog 为您做这件事:

?- member(X, [X|_T]) = member(X, [_Y| T]).
   X = _Y, _T = T.

So the _Y and X必须是相同的。他们什么时候一样了?总是,如果第一个子句为真!因此,我们需要通过在第二个子句中添加进一步的条件来排除这种情况,它们必须不同。

memberd(X, [X|_T]).
memberd(X, [Y| T]) :- dif(X,Y), memberd(X, T).
?- member(X, [a, b, a, c, a, d, b]).
   X = a
;  X = b
;  X = a
;  X = c
;  X = a
;  X = d
;  X = b
;  false.
?- memberd(X, [a, b, a, c, a, d, b]).
   X = a
;  X = b
;  X = c
;  X = d
;  false.
?- memberd(a, [a, b, a, c, a, d, b]).
   true
;  false.

可以使用以下命令改进最后一个查询library(reif)我在 Scryer 中使用它,但也可用于SICStus|SWI:

:- use_module(library(reif)).
memberd(E, [X|Xs]) :-
   if_(E = X, true, memberd(E, Xs) ).

?- memberd(a, [a, b, a, c, a, d, b]).
   true.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Prolog 成员谓词 的相关文章

随机推荐