达到变量时停止递归

时间:2014-07-27 19:16:25

标签: recursion prolog

我有一个prolog程序,搜索某些东西,每次没有找到它,它会将变量增加1.如果它从未找到用户正在搜索的内容,它将永远搜索。如果达到特殊变量,我可以停止这样做吗?这是搜索某些内容的谓词:

% ---------------------------------------------------------------------
% find(X,Y,N) :- ...search for it
% find(X,Y,N) :- ...if not found, increment N by 1 and repeat recursion
% ---------------------------------------------------------------------
find(Y,I,G) :- member(Y,I), G is 0.
find(Y,I,G) :- not(member(Y,I)), expand(I,O), find(Y,O,G1), G is G1+1.
find(Y,I,50) :- fail.

所以我想写一些类似

的东西
find(X,Y,50) :- return false

如果程序在50次递归后没有找到,那么程序返回false。 我怎么意识到这一点?

编辑:这是我的代码:http://pastebin.com/4X7BSFQ2

vwg(X,Y,G)正在搜索两个人X和Y是否与G级相关 例如:

vwg(vanessaMueller, selinaMueller, 1)

是真的,因为vanessaMueller是她的母亲

3 个答案:

答案 0 :(得分:1)

从你的pastebin

我得到了

find(Y,I,G) :- member(Y,I), G is 0.
find(Y,I,G) :- not(member(Y,I)), expand(I,O), find(Y,O,G1), G is G1+1.
find(Y,I,50) :- fail.

我会尝试

find(Y,I,0) :- member(Y,I).
find(Y,I,G) :- G < 50, not(member(Y,I)), expand(I,O), G1 is G+1, find(Y,O,G1).

答案 1 :(得分:1)

如果你总是绑定第三个参数(迭代计数),你可以简单地倒计时。一旦你达到零,你就失败了:

find( Y , I , G ) :-  %
  integer(G) ,        % enforce the contract that G must be bound
  G > 0 ,             % if we've not yet hit zero,
  member(Y,I) ,       % see if we can find Y in I
  ! .                 % and eliminate any alternatives.
find( Y , I , G ) :-  %
  integer(G) ,        % enforce the contract that G must be bound
  G > 0 ,             % if we've not yet hit zero
  G1 is G-1 ,         % decrement G
  expand(I,I1) ,      % expand I
  find(Y,I1,G1)       % and recurse down
  .                   %

请注意,上面的要求find/3的初始调用,使其第三个参数绑定到整数。

相反,如果您希望第三个参数返回计数,而不是定义限制(并使用硬编码限制),则可以使用带累加器的帮助器: / p>

find( Y , I, G ) :-
  find(Y,I,1,G)
  .

find( Y , I , G , G ) :-
  G =< 50 ,              % if we've not yet exceeded the limit
  member(Y,I) ,          % see if we can find Y in I
  ! .                    % and eliminate alternatives
find( Y , I , T , G ) :- %
  T < 50 ,               % if we're below the limit
  T1 is T+1 ,            % increment the accumulator
  expand(I,I1) ,         % expand I
  find(Y,I1,T1,G)        % and recurse down.
  .                      % easy!

或者你可以传递限制另一个参数并获得成功的递归计数:

find( Y , I, N , G ) :-
  find(Y,I,N,1,G)
  .

find( Y , I , N , G , G ) :-
  G =< N ,
  member(Y,I) ,
  ! .
find( Y , I , N , T , G ) :-
  T < N ,
  T1 is T+1 ,
  expand(I,I1) ,
  find(Y,I1,N,T1,G)
  .

有多种方法可以做到。

答案 2 :(得分:0)

根据您的口译员,您可以使用

find(X,Y,50) :- fail