Can you write between/3 in pure prolog?

爱⌒轻易说出口 提交于 2019-11-27 05:34:19
bet(N, M, K) :- N =< M, K = N.
bet(N, M, K) :- N < M, N1 is N+1, bet(N1, M, K).

In action:

$ swipl
?- [bet].
% bet compiled 0.00 sec, 1,064 bytes
true.

?- bet(1,5, K).
K = 1 n
K = 2 n
K = 3 n
K = 4 n
K = 5 n
false.

If you use a cut, you can prevent the final search failure, and recover the exact builtin between/3 behavior:

bet(N, M, K) :- N < M, K = N.
bet(N, M, K) :- N == M, !, K = N.
bet(N, M, K) :- N < M, N1 is N+1, bet(N1, M, K).

In action:

?- [bet].
% bet compiled 0.00 sec, 416 bytes
true.

?- between(1,5,K).
K = 1 n
K = 2 n
K = 3 n
K = 4 n
K = 5.

?- [bet].
% bet compiled 0.00 sec, 240 bytes
true.

?- bet(1,5,K).
K = 1 n
K = 2 n
K = 3 n
K = 4 n
K = 5.

What you're really asking is how to create a choice point. You get a solution whenever you have a successful unification. That's what happens in @seanmcl's first predicate:

bet(N, M, K) :- N =< M, K = N.

To get a choice point, you need to have alternatives. There are only two ways to get an alternative in Prolog: with an explicit "or": ;, or by supplying another rule. @seanmcl's code gives another rule, which is idiomatic for this situation.

To give another example, member/2 generates a solution for every item in the list, but there's no magic C function needed, just two rules:

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

Let's look at what happens here with member(X, [1,2]). First, the first rule is used and [X|_] is unified with [1,2], producing X=1, _=[2]. This is a successful unification, so a solution is generated. If this fails (such as by you pressing ; at the console), backtracking is initiated. The next choice point is between the two rules, so the next rule is entered. [_|Xs] unifies with [1,2], producing the binding Xs=[2] and then member(X, [2]) is called. Upon re-entry, the same decisions are available to be made again, so the first rule member(X, [X|_]) is applied and the X=2 binding is produced. This is a solution. If you backtrack again, you'll get a harmless failure because neither of the rules unify with [].

I hope this helps make sense of the situation a little bit.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!