确定术语的最大深度

Determine the maximum depth of a term

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

备注:变量、数、0元数函数符号、0元数谓词符号的深度为0。

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

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

X=3

我的努力:我实现了 max_list 谓词,但我无法进一步开发我的代码。

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

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.

列表实际上只是一个术语,带有一些简化最常见用法的语法糖。所以,我的 depth/2 定义,给定 compound/1, aggregate/3 and 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.

edit 显然,填充点没有乐趣:)[​​=14=]

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

这是一个简单明了的方法。它将列表视为平面数据结构(即使在现实中,它们是深度嵌套的 ./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!