确定术语的最大深度

时间:2015-07-02 10:11:17

标签: prolog

如何实现二元谓词,将第一个参数的深度计算为第二个参数。

备注: arity 0的变量,数字,函数符号和arity 0的谓词符号的深度为0.

术语或原子公式的深度是所有子项或子公式的最大深度 加1。

?-depth((p(X,a(q(Y)),c), X).

X=3

我的努力:我实现了max_list谓词但我无法更多地开发代码。

3 个答案:

答案 0 :(得分:1)

我认为这是朝一个方向发展的。

depth(A,0):-
 \+compound(A).
depth(A,B):-
 compound(A),
 A =.. [_H|T],
 maplist(depth,T,Depths),
 max_list(Depths,Max),
 B is Max +1.

答案 1 :(得分:1)

这是一个简单直接的方法。它将列表视为平面数据结构(即使实际上它们是一个深层嵌套的./2结构。

depth( T , D ) :- % to compute the depth of an arbitrary term...
  depth(T,0,D)    % - call the worker predicate with the accumulator seeded to zero.
  .

depth( T      , CM , MD ) :- var(T)    , ! , MD is CM+1 . % an unbound term is atomic  : its depth is the current depth + 1 .
depth( T      , CM , MD ) :- atomic(T) , ! , MD is CM+1 . % an atomic term is...atomic : its depth is the current depth + 1 .
depth( [X|Xs] , CD , MD ) :-                              % we're going to treat a list as a flat data structure (it's not really, but conceptually it is)
  findall( D , (member(T,[X|Xs),depth(T,0,D)) , Ds ) ,    % - find the depth of each item in the list
  max(Ds,N) ,                                             % - find the max depth for a list item.
  MD is CD + 1 + N                                        % - the max depth is the current depth + 1 (for the containing list) + the max depth of a list item
  .                                                       %
depth( T , CD , MD ) :-                                   % for other compound terms...
  T \= [_|_] ,                                            % - excluding lists,
  T =.. [_|Args] ,                                        % - decompose it into its functor and a list of arguments
  depth(Args,0,N) ,                                       % - compute the depth of the argument list
  MD is CD + N                                            % - the max depth is the current depth plus the depth of the argument list.
  .                                                       % Easy!

max( [N|Ns] , M ) :- max( Ns , N , M ) . % to compute the maximum value in a list, just call the worker predicate with the accumulator seeded to zero.

max( [] , M , M ) .               % when we hit the end of the list, we know the max depth.
max( [N|Ns] , T , M ) :-          % otherwise,
  ( N > T -> T1 = N ; T1 = T ) ,  % - update the current high water mark
  max(Ns,T1,M)                    % - recurse down.
  .                               % Easy!

答案 2 :(得分:0)

列表实际上只是一个术语,其中一些语法糖可以简化最常见的使用。所以,我的深度/ 2定义,给定compound / 1,aggregate / 3和arg / 3可用性的1-liner,答案如下:

?- depth(a(a,[1,2,3],c),X).
X = 4.

?- depth(p(X,a(q(Y)),c), X).
X = 3.

编辑我会很高兴你完成它:填充点

depth(T, D) :- compound(T) -> aggregate(max(B), P^A^(..., ...), M), D is M+1 ; D = 0.

编辑显然,没有乐趣填补点数:))

depth(T, D) :-
  compound(T)
  ->  aggregate(max(B+1), P^A^(arg(P, T, A), depth(A, B)), D)
  ;   D = 0.