如何实现二元谓词,将第一个参数的深度计算为第二个参数。
备注: arity 0的变量,数字,函数符号和arity 0的谓词符号的深度为0.
术语或原子公式的深度是所有子项或子公式的最大深度 加1。
?-depth((p(X,a(q(Y)),c), X).
X=3
我的努力:我实现了max_list谓词但我无法更多地开发代码。
答案 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.