prolog binary-tree dcg

prolog - lista de los valores en los nodos hoja del árbol binario T



binary-tree dcg (3)

La misma solución, no muy lejos de la primera implementación, se puede expresar como:

lea(nil, []). lea(t(X, nil, nil), [X]). lea(t(_, A, B), L) :- lea(A, L1), lea(B, L2), append(L1, L2, L) L /= [].

La última fila ( L /= [] ) se puede eliminar (si acepta la posibilidad de encontrar todas las soluciones).

Lista es la lista de valores en los nodos de hoja de un árbol binario y estoy tratando de descubrir cómo generar exactamente eso. Esto me está dando todos los nodos pero solo necesito las hojas.

lea(nil,[]). lea(t(X,L,R),[X|L]) :- lea(L,L1), lea(R,L2), append(L1,L2,L).

Ejecutar esto me da:

?- lea(t(a,t(b,t(d,nil,nil),t(e,nil,nil)),t(c,nil,t(f,t(g,nil,nil),nil))), List). List = [a, b, d, e, c, f, g]

Pero yo necesito

List = [d, e,g]

Es posible.


Primero, ampliamos if_/3 para trabajar con DCG:

if_(C_1, Then_0, Else_0) --> % if_//3 { call(C_1, Truth) }, { functor(Truth, _, 0) }, % safety check ( { Truth == true } -> phrase(Then_0) ; { Truth == false }, phrase(Else_0) ).

Usando if_//3 y if_/3 podemos manejar nodos de árbol no nulos con una cláusula (en lugar de dos):

lea3(T, Ls) :- phrase(leaves(T), Ls). leaves(nil) --> []. leaves(t(X,L,R)) --> if_(L-R = nil-nil, [X], []), leaves(L), leaves(R).


Usemos un DCG: una gramática de cláusula definida. Comenzamos con su definición original:

lea(T, L) :- phrase(values(T), L). values(nil) --> []. values(t(X,L,R)) --> [X], values(L), values(R).

Ahora, necesitamos restringirnos a esos t/3 que son hojas. Una posibilidad es enumerar todos los casos:

lea2(T, L) :- phrase(leaves(T), L). leaves(nil) --> []. leaves(t(X,nil,nil)) --> [X]. leaves(t(_,L,R)) --> { dif(L+R,nil+nil) }, leaves(L), leaves(R).

Sería aún mejor y más eficiente usar una construcción condicional similar a if_/3 . Quiero dejar esto a alguien interesado.