繁体   English   中英

Prolog 成员谓词

[英]Prolog membership predicate

我需要编写一个 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.

我知道以下内容将 output 所有这些都不管重复:

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.

所以_YX必须相同。 它们什么时候相同? 总是,如果第一个子句为真,所以我们需要通过在第二个子句中添加一个进一步的条件来排除这种情况。 它们必须不同。

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.

最后一个查询可以使用我在 Scryer 中使用的library(reif)来改进,但它也可用于SICStus | 瑞士法郎

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM