【问题标题】:Prolog recursion base caseProlog递归基本案例
【发布时间】:2019-07-29 07:19:48
【问题描述】:

我在 prolog 中有一个稍微复杂的递归函数。它的作用不是很重要,因为我很确定我的问题在于方法头。

  • V 是一个在整个函数中都不会改变的列表
  • Vset 是一个列表列表 - 在函数中,我提取其中一个单独的列表,将其乘以列表 V,然后存储该值。该单个列表将从列表列表中删除。
  • Dlist 是一个包含所有计算值的列表

    distanceAllVectors(V, [], [H|T]).
    distanceAllVectors(V, Vset, Dlist) :-   
       #function code here
    

我已经在 prolog 中跟踪了该函数,并且在某一时刻 Dlist 充满了正确的值,而 Vset 为空。这就是我需要这个函数结束的地方。

我很抱歉没有发布整个代码,但它由几种不同的方法组成,当我 99% 确定这是我的问题的根源时,这些方法需要更多时间来解释。

我对我的基本案例应该是什么以及基本案例在 prolog 中的一般工作方式感到困惑。

谢谢!

【问题讨论】:

  • Prolog 应该在基本情况下警告您有关 singletons 的信息。尝试解决此类警告。

标签: recursion prolog


【解决方案1】:

两个主要选择,您在退出递归时构建列表,或者如果您的 Prolog 支持尾调用优化,您可以使用累加器构建并使用统一退出。还要考虑的是,每种方法的距离顺序都是相反的。

建立退出列表并保留顺序:

% base case, the list being processed is empty, so are the distances
% time to start exiting the recursion
distanceAllVectors(_, [], []).
% recursive case, calculate one, process the rest, put the Distance
% onto the Distances on the way out of the recursion
distanceAllVectors(V, [HeadList|Tail], [Dist|Distances]) :-
    distanceOneVector(V, HeadList, Dist),
    distanceAllVectors(V, Tail, Distances).

使用累加器并反转顺序:

% interface to accumulator
distanceAllVectors(V, Vectors, Distances) :-
    distanceAllVectors(V, Vectors, [], Distances).

% base case, the list of vectors is emptied, unify
% Distances with the accumulator (by calling it Distances)
% Immediately exit the recursion via Tail Call Optimization
distanceAllVectors(_, [], Distances, Distances).
% recursive case, calculate one, add to accumulator and continue
distanceAllVectors(V, [HeadList|Tail], Acc, Distances) :-
    distanceOneVector(V, HeadList, Dist),
    distanceAllVectors(V, Tail, [Dist|Acc], Distances).

【讨论】:

    【解决方案2】:

    在代码中查看我的 cmets。

    % If V is the empty list, then result is the empty list. (You were missing this case.)
    distanceAllVectors([], _, []).
    
    % If Vset is the empty list, then result is the empty list.
    distanceAllVectors(_, [], []).
    
    % If V and Vset are not the empty list, the result R is
    % V multiplied by the first element S in Vset, followed
    % by the result U of multiplying V by the tail T of Vset.
    distanceAllVectors(V, [S|T], [R|U]) :-
        mult(V, S, R),                  % <-- Base case.
        distanceAllVectors(V, T, U).    % <-- Recursive case.
    
    % Multiply X by Y, result is simply m(X, Y).
    % You have to implement your real multiplication here.
     mult(X, Y, m(X, Y)).
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-27
      • 2022-01-19
      • 2017-07-11
      • 1970-01-01
      • 2017-03-04
      • 1970-01-01
      • 2020-01-25
      相关资源
      最近更新 更多