Prolog 确定术语的最大深度

Prolog 确定术语的最大深度,prolog,Prolog,如何实现二进制谓词,将第一个参数的深度计算为第二个参数 备注:数列0的变量、数字、函数符号和谓词符号的深度为0 项或原子公式的深度是所有子项或子公式的最大深度 加1 我的努力:我实现了max_list谓词,但我无法开发更多的代码。我认为这在一个方向上起作用 depth(A,0):- \+compound(A). depth(A,B):- compound(A), A =.. [_H|T], maplist(depth,T,Depths), max_list(Depths,Max),

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

备注:数列0的变量、数字、函数符号和谓词符号的深度为0

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


我的努力:我实现了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.

列表实际上只是一个术语,有一些语法使最常用的用法更简单。因此,我的深度/2定义,即给定/1、/3和/3可用性的1行代码,回答如下:

?- 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.
显然,在填充点时没有乐趣:)


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

我不确定你是否能做到这一点……你可以做到,但列表和谓词没有问题,我不确定。但我不是专家:-)@EmrysMyrooin我使用了使用库模块(库(列表)),但我也应该使用(我不能)谓词var/1、atomic/1、component/1和=../2。注意,你有一个输入错误(未闭合的括号)在您的问题中…您的定义是什么?这是常见的布局:不同谓词的子句之间只有空行。如果在子句正文中缩进4个空格而不是1个空格,则更容易阅读。:)@Lourger:或标准中的3。@Lourger:需要澄清的是:对于3个空格没有明确的规定,但是13211-1中的所有示例程序都尊重这一点。(可能是设置为宽度或3?)的选项卡。我个人不喜欢太多的凹痕,因为我的眼睛必须移动太多才能看到。@Lourger:还记得1980年的锯齿状凹痕吗?
depth(T, D) :-
  compound(T)
  ->  aggregate(max(B+1), P^A^(arg(P, T, A), depth(A, B)), D)
  ;   D = 0.
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!