如何在列表上递归时绑定变量?

时间:2016-03-12 14:20:32

标签: list recursion prolog

我在prolog列表上执行some exercises并且我已经阅读了this个问题,并看到了subtract/3实现。但我仍然有点困惑。

现在我想从给定列表中删除元素的所有出现次数,经过几次尝试后我得到了这个:

% --- del all X occurrences from a list

del_all_X(_, [], _).
% unbinded T2
del_all_X(X, [X|T], T2):-
    del_all_X(X, T, T2).
    %!.  ERROR: see below
del_all_X(Y, [X|T], [X|T2]):-
    dif(Y, X),   % USE this instead of !
    del_all_X(Y, T, T2).

这给了我这种输出:

25 ?- del_all_X(x, [x,a,b,x,d,e,x,x], X).
X = [a, b, d, e|_G4115].
  • 绑定自由变量时哪种思维方式正确(如 T2 _ )?
  • 如何获得 clean 输出?
  

回答:del_all_X(_,[],[])。

  • 是否有更简单的实现而无需校准外部函数?

由于

编辑:在问题和代码中添加了更正和答案。

1 个答案:

答案 0 :(得分:1)

  • 根据我的理解,使用 cut 是不合适的,因为这可能会以意想不到的方式中断堆栈树的增长,因为它避免了使用不同值的第二个规则的统一已经统一的第一条规则。 learn prolog now - cut

  • 使用 dif 是必不可少的,因为当搜索的元素(Y)不同于给定列表(X)的第一个时,它避免了第二个规则的统一,在此使用不同变量调用此元素的情况是不够的。 @false给出的例子澄清了。 见Using \== or dif

    % With ! and Without dif
    [debug] ?- del_all_X(x, [x], [x]).
     T Call: (7) del_all_X(x, [x], [x])
     T Call: (8) del_all_X(x, [], [x])
     T Fail: (8) del_all_X(x, [], [x])
     T Redo: (7) del_all_X(x, [x], [x])
     T Call: (8) del_all_X(x, [], [])
     T Exit: (8) del_all_X(x, [], [])
     T Exit: (7) del_all_X(x, [x], [x])
    true .
    

    更新版本:

    del_all_X(_, [], []).
    del_all_X(X, [X|T], T2):-
        del_all_X(X, T, T2).
    del_all_X(Y, [X|T], [X|T2]):-
        %  X \== Y 
        dif(Y, X),     
        del_all_X(Y, T, T2).
    
    
    [debug] 7 ?- del_all_X(x, [x], [x]).
     T Call: (7) del_all_X(x, [x], [x])
     T Call: (8) del_all_X(x, [], [x])
     T Fail: (8) del_all_X(x, [], [x])
     T Redo: (7) del_all_X(x, [x], [x])
     T Fail: (7) del_all_X(x, [x], [x])
    false.