OLEH:
DIMAS RAMADHAN
150535602458
S1 TEKNIK INFORMATIKA 2015
OFFERING A
FAKULTAS TEKNIK
MARET 2017
Source Code
istree(nil).
istree(t(_,L,R)):-istree(L),istree(R).
Hasil
Penjelasan:
Source Code
imbang(0,nil):-!.
imbang(N,t(x,L,R)):-
N>0,
N0 is N-1,
N1 is N0//2,
N2 is N0-N1,
distrib(N1,N2,NL,NR),
imbang(NL,L),imbang(NR,R).
distrib(N,N,N,N):-!.
distrib(N1,N2,N1,N2).
distrib(N1,N2,N2,N1).
Hasil
Penjelasan:
Sourcecode diatas digunakan untuk membuat suatu kombinasi tree yang seimbang.
Didalam program node akan ditandai x. Pada prolog dituliskan imbang(5,X) dimana dimana 5
adalah N dan X adalah variable hasil. Seperti pada hasil diatas, saat dimasukkan imbang(5,X)
pada prolog akan menghasilkan salah satunya X=t(x,t(x,nil,t(x,nil,nil)),t(x,nil,t(x,nil,nil))).
Dimana tree akan memiliki sebuah node x, yang memiliki 2 percabangan x, dan tiap cabang x
memiliki satu percabangan x pada node kanan. Ada 4 kombinasi untuk penyelesaian tree dengan
5 nodes.
Source Code
simetris(nil).
simetris(t(_,L,R)) :- mirror(L,R).
mirror(nil,nil).
mirror(t(_,L1,R1),t(_,L2,R2)) :- mirror(L1,R2), mirror(R1,L2).
Hasil
Penjelasan:
Sourcecode diatas digunakan untuk memeriksa, apakah tree tersebut simetris atau tidak.
Sebuah tree dipat dikatakan simetris jika memiliki jumlah node kiri dan kanan sama. Seperti
pada pemanggilan pertama, tree bernilai true karena node d memiliki cabang kiri node i, dan
cabang kanan node m sehingga simetris. Namun pada pemanggilan kedua, node d memiliki
cabang kiri node i, tapi tidak memiliki cabang kanan sehingga tidak simetris.
Source Code
add(X,nil,t(X,nil,nil)).
add(X,t(Root,L,R),t(Root,L1,R)) :- X @< Root, add(X,L,L1).
add(X,t(Root,L,R),t(Root,L,R1)) :- X @> Root, add(X,R,R1).
construct(L,T) :- construct(L,T,nil).
construct([],T,T).
construct([N|Ns],T,T0) :- add(N,T0,T1), construct(Ns,T,T1).
test_symmetric(L) :- construct(L,T), simetris(T).
Hasil
Penjelasan:
Sourcecode kali ini adalah membuat sebuah binary tree dengan hanya memasukkan
sebuah list. List tersebut akan diubah menjadi nodes. Nilai pertama kali akan dijadikan menjadi
sebuah root, selanjutnya node dengan nilai lebih kecil dari parent akan berada dikiri, jika lebih
besar akan berada dikanan. Seperti pada hasil diata, terdapat nilai [11,33,4,6,5], saat dijalankan
maka akan menghasilkan tree seperti pada X, dimana 11 adalah root, selanjutnya 33
dibandingkan dengan 11, karena lebih besar maka akan diletakkan pada cabang kanan. Lalu
membandingkan 4 dengan 11, karena lebih kecil maka 4 akan menjadi cabang dikiri. Selanjutnya
meletakkan node 6 dengan membandingkan terlebih dahulu dengan 11, karena lebih kecil maka
akan masuk kecabang kiri, selanjutnya dibandingkan dengan 4, karena lebih besar maka akan
menjadi cabang kanan. Yang terakhir memasukkan node 5 dengan cara yang sama. Pertama
membandingkan dengan 11, karena lebih kecil masuk kekiri, dibandingkan dengan 4, karena
lebih besar masuk kekanan, lalu dibandingkan dengan 6, karena lebih kecil maka akan masuk
kecabang kiri. Proses pun selesai. Jadi peletakkan node baru dilakukan dengan membandingkan
nilai dengan nilai node yang sudah terpasang.
Source Code
Penjelasan:
Sourcecode diatas digunakan untuk membuat sebuah tree yang seimbang dan simetris,
jika tree yang akan dibuat tidak seimbang maupun simetris maka akan menghasilkan nilai false,
jika seimbang ataupun simetris maka akan menghasilkan tree nya. Agar dapat menghasilkan tree
yang seimbang maupun simetris maka jumlah node haruslah ganjil. Karena saat genap maka aka
nada node yang tidak simetris dengan node sebelahnya.
Source Code
hbal_tree(0,nil) :- !.
hbal_tree(1,t(x,nil,nil)) :- !.
hbal_tree(D,t(x,L,R)) :- D > 1,
D1 is D - 1, D2 is D - 2,
distr(D1,D2,DL,DR),
hbal_tree(DL,L), hbal_tree(DR,R).
distr(D1,_,D1,D1).
distr(D1,D2,D1,D2).
distr(D1,D2,D2,D1).
Hasil
Penjelasan:
Sourcecode diatas digunakan untuk membuat sebuah tree yang seimbang dengan
memasukkan kedalaman atau ketinggian yang diinginkan. Seperti pada hasil, hbal_tree(2,X)
akan menghasilkan 3 buah tree dengan kedalaman 2. Begitupula untuk hbal_tree(3,X) yang
menghasilkan tree dengan kedalaman 3.
Source Code
minNodes(0,0) :- !.
minNodes(1,1) :- !.
minNodes(H,N) :- H > 1,
H1 is H - 1, H2 is H - 2,
minNodes(H1,N1), minNodes(H2,N2),
N is 1 + N1 + N2.
maxNodes(H,N) :- N is 2**H - 1.
minHeight(0,0) :- !.
minHeight(N,H) :- N > 0, N1 is N//2, minHeight(N1,H1), H is H1+1.
maxHeight(N,H) :- maxHeight(N,H,1,1).
maxHeight(N,H,H1,N1) :- N1 > N, !, H is H1 - 1.
maxHeight(N,H,H1,N1) :- N1 =< N,
H2 is H1 + 1, minNodes(H2,N2), maxHeight(N,H,H2,N2).
hbal_tree_nodes(N,T) :-
minHeight(N,Hmin), maxHeight(N,Hmax),
between(Hmin,Hmax,H),
hbal_tree(H,T), nodes(T,N).
nodes(nil,0).
nodes(t(_,Left,Right),N) :-
nodes(Left,NLeft),
nodes(Right,NRight),
N is NLeft + NRight + 1.
count_hbal_trees(N,C) :- setof(T,hbal_tree_nodes(N,T),Ts),
length(Ts,C).
Hasil
Penjelasan:
Source code diatas membuat sebuah node yang seimbang dengan ketinggian dan jumlah
nodes. Jadi pada program dapat dilakukan penghitungan minimal nodes yang dibutuhkan jika
tinggi dari tree adalah sekian. Begitupula dengan ketinggian, dapat dihitung dengan memasukkan
nilai jumlah nodes. Selanjutnya hbal_tree_nodes digunakan untuk membuat tree sesuai inputan
jumlah nodes, lalu akan dihitung ketinggihan maksimal dan minimal untuk tree dengan jumlah
nodes yang sudah dimasukkan, lalu dibuat tree dengan ketinggihan maksimal dan minimal
tersebut. Seperti pada contoh, hbal_tree_nodes(3,X) akan memiliki ketinggihan maksimal dan
minimal 2, sehingga akan menjadi seperti pada hasil diatas. Untuk hbal_tree_nodes(4,X) akan
menghasilkan tinggi maksimal dan minimal 3 sehingga akan menjadi tree dengan variasi diatas.
8. Menghitung jumlah leaf pada binary tree
Source Code
daun(nil,0).
daun(t(_,nil,nil),1).
daun(t(_,L,nil),N) :- L = t(_,_,_), daun(L,N).
daun(t(_,nil,R),N) :- R = t(_,_,_), daun(R,N).
daun(t(_,L,R),N) :- L = t(_,_,_), R = t(_,_,_),
daun(L,NL), daun(R,NR), N is NL + NR.
Hasil
Penjelasan:
Sourcecode diatas digunakan untuk menghitung jumlah leafs dari sebuah tree. Leafs
sendiri merupakan node paling bawah dimana nodes tersebut tidak memiliki child atau
percabangan. Jadi seperti pada hasil diatas, daun(t(d,t(i,nil,nil),nil),X) akan menghasilkan X=1
karena tree akan memiliki root d, yang bercabang menjadi i. Dan i tidak memiliki cabang
sehingga i adalah leaf.
Source Code
leaves(nil,[]).
leaves(t(X,nil,nil),[X]).
leaves(t(_,L,nil),S) :- L = t(_,_,_), leaves(L,S).
leaves(t(_,nil,R),S) :- R = t(_,_,_), leaves(R,S).
leaves(t(_,L,R),S) :- L = t(_,_,_), R = t(_,_,_),
leaves(L,SL), leaves(R,SR), append(SL,SR,S).
Hasil
Penjelasan:
Source Code
internals(nil,[]).
internals(t(_,nil,nil),[]).
internals(t(X,L,nil),[X|S]) :- L = t(_,_,_), internals(L,S).
internals(t(X,nil,R),[X|S]) :- R = t(_,_,_), internals(R,S).
internals(t(X,L,R),[X|S]) :- L = t(_,_,_), R = t(_,_,_),
internals(L,SL), internals(R,SR), append(SL,SR,S).
Hasil
Penjelasan:
Sourcecode kali ini digunakan untuk mencari internal nodes. Internal nodes sendiri
merupakan node yang memiliki 1 atau dua child, atau dapat juga disebut parents. Seperti pada
hasil diatas, terdapat sebuah tree dengan root d yang memiliki 2 child yaitu i dan a. Node i
memiliki 1 child yaitu node m, sedangkan node a memiliki child yaitu s. Jadi saat
internals(t(d,t(i,nil,t(m,nil,nil)),t(a,nil,t(s,nil,nil))),X) dijalankan maka akan menghasilkan
X=[d,i,a]
Source Code
atlevel(nil,_,[]).
atlevel(t(X,_,_),1,[X]).
atlevel(t(_,L,R),D,S) :- D > 1, D1 is D-1,
atlevel(L,D1,SL), atlevel(R,D1,SR), append(SL,SR,S).
Hasil
Penjelasan:
Sourcecode ini digunakan untuk menampilkan nodes pada level tertentu dalam bentuk
list. Didalam atlevel diinputkan sebuah tree, lalu kedalaman yang diinginkan dan akan
menampilkan node yang berada pada kedalaman tersebut. Jadi pada prolog dideklarasikan
atlevel(t(d,t(i,nil,nil),t(m,nil,nil)),2X) lalu dijalankan dan akan menghasilkan X=[i,m] karena
pada lever 2 hanya terdapat nodes i dan m
Source Code
complete_binary_tree(N,T) :- complete_binary_tree(N,T,1).
complete_binary_tree(N,nil,A) :- A > N, !.
complete_binary_tree(N,t(_,L,R),A) :- A =< N,
AL is 2 * A, AR is AL + 1,
complete_binary_tree(N,L,AL),
complete_binary_tree(N,R,AR).
Hasil
Penjelasan:
Sourcecode diatas digunakan untuk menentukan jumlah nodes dalam complete binary
tree. Complete binary tree sendiri adalah sebuah tree yang subtree boleh memiliki panjang path
yang berbeda dari tiap node. Pada program ini, dimasukkan sebuah angka yang merupakan
jumlah dari nodes sebuah tree, jika angka tersebut memiliki jumlah yang sama seperti pada
complete binary tree yang dibuat makan akan menghasilkan nilai true. Jadi pada prolog
dideklarasikan complete_binary_tree(3, t(d,t(i,nil,nil),t(m,nil,nil))), saat dijalankan maka akan
menghasilkan nilai true, karena jumlah nodes pada tree tersebut 3. Namun berbeda lagi saat
dimasukkan nilai 4, karena jumlah tidak sama maka akan menghasilkan nilai false.
Source Code
layout_binary_tree(T,PT) :- layout_binary_tree(T,PT,1,_,1).
layout_binary_tree(nil,nil,I,I,_).
layout_binary_tree(t(W,L,R),t(W,X,Y,PL,PR),Iin,Iout,Y) :-
Y1 is Y + 1,
layout_binary_tree(L,PL,Iin,X,Y1),
X1 is X + 1,
layout_binary_tree(R,PR,X1,Iout,Y1).
Hasil
Penjelasan:
Pada program kali ini akan dibuat sourcecode untuk memetakan sebuah binarytree
dengan pemetaan koordinat sumbu X dan Y dimana X adalah posisi inorder dan y merupakan
kedalaman tree. Pada layout_binary_tree diinputkan sebuah tree yang nantinya akan
menghasilkan output sebuah tree namun dengan posisi dari nodes tree tersebut. Seperti contoh
layout_binary_tree(t(d,t(i,nil,nil),t(m,nil,nil)),X) maka saat dijalankan akan menghasilkan X=
t(d,2,1,t(i,1,2,nil,nil),t(m,3,2,nil.nil). Jadi output tersebut berarti tree tersebut memiliki node d
pada posisi(2,1) yang berarti pada barisan kedua dikedalaman pertama atau level 1, i pada
posisi(1,2), dan m pada posisi(3,2). Jadi pada setiap node akan memiliki posisi koordinat untuk
mengetahui penggambaran letak nodes tree.
Source Code
layout_binary_tree2(nil,nil) :- !.
layout_binary_tree2(T,PT) :-
hor_dist(T,D4), D is D4//4, x_pos(T,X,D),
layout_binary_tree2(T,PT,X,1,D).
hor_dist(nil,1).
hor_dist(t(_,L,R),D4) :-
hor_dist(L,D4L),
hor_dist(R,D4R),
D4 is 2 * max(D4L,D4R).
x_pos(t(_,nil,_),1,_) :- !.
x_pos(t(_,L,_),X,D) :- D2 is D//2, x_pos(L,XL,D2), X is XL+D.
layout_binary_tree2(nil,nil,_,_,_).
layout_binary_tree2(t(W,L,R),t(W,X,Y,PL,PR),X,Y,D) :-
Y1 is Y + 1,
Xleft is X - D,
D2 is D//2,
layout_binary_tree2(L,PL,Xleft,Y1,D2),
Xright is X + D,
layout_binary_tree2(R,PR,Xright,Y1,D2).
Hasil
Penjelasan:
Program ini sama seperti sebelumnya, memetakan sebuah binarytree dengan pemetaan
koordinat sumbu X dan Y dimana X adalah posisi inorder dan y merupakan kedalaman tree.
Perbedaanya adalah dalam layout binary tree ini membutuhkan sumbu x yang lebih panjang
sehingga membutuhkan layout yang besar. Seperti contoh
layout_binary_tree(t(d,t(i,nil,nil),t(m,nil,nil)),X) maka saat dijalankan akan menghasilkan X=
t(d,2,1,t(i,1,2,nil,nil),t(m,3,2,nil.nil). Jadi output tersebut berarti tree tersebut memiliki node d
pada posisi(2,1) yang berarti pada barisan kedua dikedalaman pertama atau level 1, i pada
posisi(1,2), dan m pada posisi(3,2). Sama seperti hasil program sebelumnya.
Source Code
layout_binary_tree3(nil,nil) :- !.
layout_binary_tree3(T,PT) :-
contour_tree(T,CT), % construct the "contour" tree CT
CT = t(_,_,_,Contour),
mincont(Contour,MC,0), % find the position of the leftmost node
Xroot is 1-MC,
layout_binary_tree3(CT,PT,Xroot,1).
contour_tree(nil,nil).
contour_tree(t(X,L,R),t(X,CL,CR,Contour)) :-
contour_tree(L,CL),
contour_tree(R,CR),
combine(CL,CR,Contour).
combine(nil,nil,[]).
combine(t(_,_,_,CL),nil,[c(-1,-1)|Cs]) :- shift(CL,-1,Cs).
combine(nil,t(_,_,_,CR),[c(1,1)|Cs]) :- shift(CR,1,Cs).
combine(t(_,_,_,CL),t(_,_,_,CR),[c(DL,DR)|Cs]) :-
maxdiff(CL,CR,MD,0),
DR is (MD+2)//2, DL is -DR,
merge(CL,CR,DL,DR,Cs).
shift([],_,[]).
shift([c(L,R)|Cs],S,[c(LS,RS)|CsS]) :-
LS is L+S, RS is R+S, shift(Cs,S,CsS).
maxdiff([],_,MD,MD) :- !.
maxdiff(_,[],MD,MD) :- !.
maxdiff([c(_,R1)|Cs1],[c(L2,_)|Cs2],MD,A) :-
A1 is max(A,R1-L2),
maxdiff(Cs1,Cs2,MD,A1).
merge([],CR,_,DR,Cs) :- !, shift(CR,DR,Cs).
merge(CL,[],DL,_,Cs) :- !, shift(CL,DL,Cs).
merge([c(L1,_)|Cs1],[c(_,R2)|Cs2],DL,DR,[c(L,R)|Cs]) :-
L is L1+DL, R is R2+DR,
merge(Cs1,Cs2,DL,DR,Cs).
mincont([],MC,MC).
mincont([c(L,_)|Cs],MC,A) :-
A1 is min(A,L), mincont(Cs,MC,A1).
layout_binary_tree3(nil,nil,_,_).
layout_binary_tree3(t(W,nil,nil,_),t(W,X,Y,nil,nil),X,Y) :- !.
layout_binary_tree3(t(W,L,R,[c(DL,DR)|_]),t(W,X,Y,PL,PR),X,Y) :-
Y1 is Y + 1,
Xleft is X + DL,
layout_binary_tree3(L,PL,Xleft,Y1),
Xright is X + DR,
layout_binary_tree3(R,PR,Xright,Y1).
Hasil
Penjelasan:
Source Code
a
tree_string(T,S) :- nonvar(T), !, tree_to_string(T,S).
tree_string(T,S) :- nonvar(S), string_to_tree(S,T).
tree_dlist(nil,L-L).
tree_dlist(t(X,nil,nil),L1-L2) :-
letter(X,L1-L2).
tree_dlist(t(X,Left,Right),L1-L7) :-
letter(X,L1-L2),
symbol('(',L2-L3),
tree_dlist(Left,L3-L4),
symbol(',',L4-L5),
tree_dlist(Right,L5-L6),
symbol(')',L6-L7).
symbol(X,[X|Xs]-Xs).
letter(X,L1-L2) :- symbol(X,L1-L2), char_type(X,alpha).
Hasil
a.
b.
Penjelasan:
Sourcecode diatas digunakan untuk menampilkan node sebuah tree dalam bentuk string
dengan posisi yang sama seperti pada tree. Dua sourcecode diatas memiliki output yang sama
namun dengan sourcecode yang berbeda. Kedua sourcode tersebut menghasilkan nilai yang
sama, yang membedakan hanyalah waktu dan penulisan sintaks yang lebih sedikit. Dan
tree_string1 lebih cepat dan sedikit dalam penulisan sintaksnya. Untuk menjalankannya pada
prolog dideklarasikan tree_string berisi tree yang nantinya akan menghasilkan output susunan
nodes tree dalam bentuk string. Seperti contoh
tree_string(t(d,t(i,nil,nil),t(m,t(a,nil,nil),t(s,nil,nil))),X) saat dieksekusi maka akan menghasilkan
output X= d(i,m(a,s)) yang dapat berarti d memiliki child i dikiri dan m dikanan, m sendiri
memiliki child a dikiri dan s dikanan
Source Code
preorder_tl(nil,[]).
preorder_tl(t(X,Left,Right),[X|List]) :-
preorder_tl(Left,ListLeft),
preorder_tl(Right,ListRight),
append(ListLeft,ListRight,List).
inorder(T,S) :- inorder_tl(T,L), atom_chars(S,L).
inorder_tl(nil,[]).
inorder_tl(t(X,Left,Right),List) :-
inorder_tl(Left,ListLeft),
inorder_tl(Right,ListRight),
append(ListLeft,[X|ListRight],List).
b
preorder_tl1(nil,[]).
preorder_tl1(t(X,Left,Right),[X|List]) :-
preorder_tl1(Left,ListLeft),
preorder_tl1(Right,ListRight),
append(ListLeft,ListRight,List).
preorder_lt1(nil,[]).
preorder_lt1(t(X,Left,Right),[X|List]) :-
append(ListLeft,ListRight,List),
preorder_lt1(Left,ListLeft),
preorder_lt1(Right,ListRight).
inorder1(T,S) :- nonvar(T), !, inorder_tl(T,L), atom_chars(S,L).
inorder1(T,S) :- atom(S), atom_chars(S,L), inorder_lt(T,L).
inorder_tl1(nil,[]).
inorder_tl1(t(X,Left,Right),List) :-
inorder_tl1(Left,ListLeft),
inorder_tl1(Right,ListRight),
append(ListLeft,[X|ListRight],List).
inorder_lt1(nil,[]).
inorder_lt1(t(X,Left,Right),List) :-
append(ListLeft,[X|ListRight],List),
inorder_lt1(Left,ListLeft),
inorder_lt1(Right,ListRight).
c
pre_in_tree_push(P,I,T) :-
atom_chars(P,PL), atom_chars(I,IL), pre_in_tree_pu(PL,IL,T).
pre_in_tree_pu([],[],nil).
pre_in_tree_pu([X|PL],IL,t(X,Left,Right)) :-
append(ILeft,[X|IRight],IL),
append(PLeft,PRight,PL),
pre_in_tree_pu(PLeft,ILeft,Left),
pre_in_tree_pu(PRight,IRight,Right).
d
pre_in_tree_d(P,I,T) :-
atom_chars(P,PL), atom_chars(I,IL), pre_in_tree_dl(PL-[],IL-[],T).
pre_in_tree_dl(P-P,I-I,nil).
pre_in_tree_dl(P1-P4,I1-I4,t(X,Left,Right)) :-
symbol1(X,P1-P2), symbol1(X,I2-I3),
pre_in_tree_dl(P2-P3,I1-I2,Left),
pre_in_tree_dl(P3-P4,I3-I4,Right).
symbol1(X,[X|Xs]-Xs).
Hasil
a.
b.
c.
d.
Penjelasan:
Pada sourcecode a dan b merupakan program untuk menampilkan nodes dalam preorder
dan inorder. Preorder sendiri merupakan cara pembacaan dari root kearah kanan hingga tidak
ditemui child lagi, lalu dari root kekiri. Sedangkan inorder merupakan pembacaan tree dari
subtree paling kiri ke kanan. Untuk menjalankan programnya pada prolog dideklarasikan
preorder atau inorder ataupun preorder1 atau inorder1 yang didalamnya dideklarasikan tree dan
nantinya akan menghasilkan output nodes yang dibaca secara preorder atau inorder.
Pada sourcecode c digunakan untuk membaca sebuah tree secara preorder dan inorder
dalam satu kali eksekusi. Jadi pada prolog dideklarasikan pre_in_tree yang didalamnya
dideklarasikan 2 variable untuk output, variable pertaama untuk preorder dan variable kedua
untuk inorder, lalu dideklarasikan tree yang akan dieksekusi. Seperti pada hasil point c diatas,
pre_in_tree(P,I,t(d,t(i,nil,nil),t(m,t(a,nil,nil),t(s,nil,nil)))), saat dijalankan maka tree akan diproses
dan menghasilkan output P=dimas yang berarti tree dibaca secara preorder, dan I=idams yang
berarti tree dibaca secara inorder
Untuk sourcecode point d digunakan untuk memenuhi syarat preorder dan inorder. disana
diinputkan deretan nama nodes yang dibaca secara preorder dan inorder, saat dieksekusi maka
akan menghasilkan output sebuah tree yang memenuhi syarat preorder dan inorder tersebut.
dots(nil,L1-L2) :- sy('.',L1-L2).
dots(t(X,Left,Right),L1-L4) :-
letter(X,L1-L2),
dots(Left,L2-L3),
dots(Right,L3-L4).
sy(X,[X|Xs]-Xs).
Penjelasan:
Sourcecode ini digunakan untuk mengubah tree menjadi sebuah string dengan nil akan
disimbilkan menjadi titik. Pada prolog dideklarasikan tree_dotstring kemudian diinputkan tree
dan nantinya akan menghasilkan sebuah string berisi nodes dalam tree tersebut. Seperti pada
hasil diatas, dideklarasikan dotstring(t(d,t(i,nil,nil),t(m,nil,nil)),X) maka saat dieksekusi akan
menghasilkan X= di..m.. dimana titik(.) merepresentasikan nil.
KESIMPULAN
Pada modul ini kita mempelajari tentang cara pembuatan hingga pengolahan dari sebuah binary
tree. Terdapat berbagai macam cara untuk mengolah tree menggunakan prolog, seperti
menghitung kedalaman tree, leafes tree, jumlah nodes pada level tertentu dan lainnya. Selain itu
kita dapat membaca nodes didalam tree dengan preorder dan inorder maupun sebaliknya,
membuat sebuah tree menggunakan preorder dan inorder yang nantinya dapat dihasilkan dengan
sebuah string ataupun dotstring.
LAMPIRAN
SCRIPT
distrib(N,N,N,N):-!.
distrib(N1,N2,N1,N2).
distrib(N1,N2,N2,N1).
maxNodes(H,N) :- N is 2**H - 1.
minHeight(0,0) :- !.
minHeight(N,H) :- N > 0, N1 is N//2, minHeight(N1,H1), H is H1+1.
maxHeight(N,H) :- maxHeight(N,H,1,1).
maxHeight(N,H,H1,N1) :- N1 > N, !, H is H1 - 1.
maxHeight(N,H,H1,N1) :- N1 =< N,
H2 is H1 + 1, minNodes(H2,N2), maxHeight(N,H,H2,N2).
hbal_tree_nodes(N,T) :-
minHeight(N,Hmin), maxHeight(N,Hmax),
between(Hmin,Hmax,H),
hbal_tree(H,T), nodes(T,N).
nodes(nil,0).
nodes(t(_,Left,Right),N) :-
nodes(Left,NLeft),
nodes(Right,NRight),
N is NLeft + NRight + 1.
count_hbal_trees(N,C) :- setof(T,hbal_tree_nodes(N,T),Ts),
length(Ts,C).
%shorter program
daun1(nil,0).
daun1(t(_,nil,nil),1):-!.
daun1(t(_,L,R),N):-daun1(L,NL),daun1(R,NR), N is NL+NR.
leaves(nil,[]).
leaves(t(X,nil,nil),[X]).
leaves(t(_,L,nil),S) :- L = t(_,_,_), leaves(L,S).
leaves(t(_,nil,R),S) :- R = t(_,_,_), leaves(R,S).
leaves(t(_,L,R),S) :- L = t(_,_,_), R = t(_,_,_),
leaves(L,SL), leaves(R,SR), append(SL,SR,S).
%shorter programs
leaves1(nil,[]).
leaves1(t(X,nil,nil),[X]) :- !.
leaves1(t(_,L,R),S) :-
leaves1(L,SL), leaves1(R,SR), append(SL,SR,S).
%
nnodes(nil,0) :- !.
nnodes(t(_,L,R),N) :- N > 0, N1 is N-1,
between(0,N1,NL), NR is N1-NL,
nnodes(L,NL), nnodes(R,NR).
leaves2(T,S) :- leaves2(T,S,0).
leaves2(T,S,N) :- nnodes(T,N), leaves1(T,S).
leaves2(T,S,N) :- N1 is N+1, leaves2(T,S,N1).
internals(nil,[]).
internals(t(_,nil,nil),[]).
internals(t(X,L,nil),[X|S]) :- L = t(_,_,_), internals(L,S).
internals(t(X,nil,R),[X|S]) :- R = t(_,_,_), internals(R,S).
internals(t(X,L,R),[X|S]) :- L = t(_,_,_), R = t(_,_,_),
internals(L,SL), internals(R,SR), append(SL,SR,S).
internals1(nil,[]).
internals1(t(_,nil,nil),[]) :- !.
internals1(t(X,L,R),[X|S]) :-
internals1(L,SL), internals1(R,SR), append(SL,SR,S).
internals2(nil,[]).
internals2(t(X,L,R),[X|S]) :-
append(SL,SR,S), internals2(L,SL), internals2(R,SR).
% 11. Memasukkan nodes binary tree pada level tertentu kedalam list.
atlevel(nil,_,[]).
atlevel(t(X,_,_),1,[X]).
atlevel(t(_,L,R),D,S) :- D > 1, D1 is D-1,
atlevel(L,D1,SL), atlevel(R,D1,SR), append(SL,SR,S).
%shorter programs
levelorder(T,S) :- levelorder(T,S,1).
levelorder(T,[],D) :- atlevel(T,D,[]), !.
levelorder(T,S,D) :- atlevel(T,D,SD),
D1 is D+1, levelorder(T,S1,D1), append(SD,S1,S).
complete_binary_tree(N,T) :- complete_binary_tree(N,T,1).
complete_binary_tree(N,nil,A) :- A > N, !.
complete_binary_tree(N,t(_,L,R),A) :- A =< N,
AL is 2 * A, AR is AL + 1,
complete_binary_tree(N,L,AL),
complete_binary_tree(N,R,AR).
layout_binary_tree(T,PT) :- layout_binary_tree(T,PT,1,_,1).
layout_binary_tree(nil,nil,I,I,_).
layout_binary_tree(t(W,L,R),t(W,X,Y,PL,PR),Iin,Iout,Y) :-
Y1 is Y + 1,
layout_binary_tree(L,PL,Iin,X,Y1),
X1 is X + 1,
layout_binary_tree(R,PR,X1,Iout,Y1).
hor_dist(nil,1).
hor_dist(t(_,L,R),D4) :-
hor_dist(L,D4L),
hor_dist(R,D4R),
D4 is 2 * max(D4L,D4R).
x_pos(t(_,nil,_),1,_) :- !.
x_pos(t(_,L,_),X,D) :- D2 is D//2, x_pos(L,XL,D2), X is XL+D.
layout_binary_tree2(nil,nil,_,_,_).
layout_binary_tree2(t(W,L,R),t(W,X,Y,PL,PR),X,Y,D) :-
Y1 is Y + 1,
Xleft is X - D,
D2 is D//2,
layout_binary_tree2(L,PL,Xleft,Y1,D2),
Xright is X + D,
layout_binary_tree2(R,PR,Xright,Y1,D2).
contour_tree(nil,nil).
contour_tree(t(X,L,R),t(X,CL,CR,Contour)) :-
contour_tree(L,CL),
contour_tree(R,CR),
combine(CL,CR,Contour).
combine(nil,nil,[]).
combine(t(_,_,_,CL),nil,[c(-1,-1)|Cs]) :- shift(CL,-1,Cs).
combine(nil,t(_,_,_,CR),[c(1,1)|Cs]) :- shift(CR,1,Cs).
combine(t(_,_,_,CL),t(_,_,_,CR),[c(DL,DR)|Cs]) :-
maxdiff(CL,CR,MD,0),
DR is (MD+2)//2, DL is -DR,
merge(CL,CR,DL,DR,Cs).
shift([],_,[]).
shift([c(L,R)|Cs],S,[c(LS,RS)|CsS]) :-
LS is L+S, RS is R+S, shift(Cs,S,CsS).
maxdiff([],_,MD,MD) :- !.
maxdiff(_,[],MD,MD) :- !.
maxdiff([c(_,R1)|Cs1],[c(L2,_)|Cs2],MD,A) :-
A1 is max(A,R1-L2),
maxdiff(Cs1,Cs2,MD,A1).
merge([],CR,_,DR,Cs) :- !, shift(CR,DR,Cs).
merge(CL,[],DL,_,Cs) :- !, shift(CL,DL,Cs).
merge([c(L1,_)|Cs1],[c(_,R2)|Cs2],DL,DR,[c(L,R)|Cs]) :-
L is L1+DL, R is R2+DR,
merge(Cs1,Cs2,DL,DR,Cs).
mincont([],MC,MC).
mincont([c(L,_)|Cs],MC,A) :-
A1 is min(A,L), mincont(Cs,MC,A1).
layout_binary_tree3(nil,nil,_,_).
layout_binary_tree3(t(W,nil,nil,_),t(W,X,Y,nil,nil),X,Y) :- !.
layout_binary_tree3(t(W,L,R,[c(DL,DR)|_]),t(W,X,Y,PL,PR),X,Y) :-
Y1 is Y + 1,
Xleft is X + DL,
layout_binary_tree3(L,PL,Xleft,Y1),
Xright is X + DR,
layout_binary_tree3(R,PR,Xright,Y1).
tree_dlist(nil,L-L).
tree_dlist(t(X,nil,nil),L1-L2) :-
letter(X,L1-L2).
tree_dlist(t(X,Left,Right),L1-L7) :-
letter(X,L1-L2),
symbol('(',L2-L3),
tree_dlist(Left,L3-L4),
symbol(',',L4-L5),
tree_dlist(Right,L5-L6),
symbol(')',L6-L7).
symbol(X,[X|Xs]-Xs).
letter(X,L1-L2) :- symbol(X,L1-L2), char_type(X,alpha).
preorder_tl(nil,[]).
preorder_tl(t(X,Left,Right),[X|List]) :-
preorder_tl(Left,ListLeft),
preorder_tl(Right,ListRight),
append(ListLeft,ListRight,List).
inorder(T,S) :- inorder_tl(T,L), atom_chars(S,L).
inorder_tl(nil,[]).
inorder_tl(t(X,Left,Right),List) :-
inorder_tl(Left,ListLeft),
inorder_tl(Right,ListRight),
append(ListLeft,[X|ListRight],List).
% 17.b.
preorder1(T,S) :- nonvar(T), !, preorder_tl1(T,L), atom_chars(S,L).
preorder1(T,S) :- atom(S), atom_chars(S,L), preorder_lt1(T,L).
preorder_tl1(nil,[]).
preorder_tl1(t(X,Left,Right),[X|List]) :-
preorder_tl1(Left,ListLeft),
preorder_tl1(Right,ListRight),
append(ListLeft,ListRight,List).
preorder_lt1(nil,[]).
preorder_lt1(t(X,Left,Right),[X|List]) :-
append(ListLeft,ListRight,List),
preorder_lt1(Left,ListLeft),
preorder_lt1(Right,ListRight).
inorder_tl1(nil,[]).
inorder_tl1(t(X,Left,Right),List) :-
inorder_tl1(Left,ListLeft),
inorder_tl1(Right,ListRight),
append(ListLeft,[X|ListRight],List).
inorder_lt1(nil,[]).
inorder_lt1(t(X,Left,Right),List) :-
append(ListLeft,[X|ListRight],List),
inorder_lt1(Left,ListLeft),
inorder_lt1(Right,ListRight).
% 17.c.
pre_in_tree(P,I,T) :- preorder(T,P), inorder(T,I).
pre_in_tree_push(P,I,T) :-
atom_chars(P,PL), atom_chars(I,IL), pre_in_tree_pu(PL,IL,T).
pre_in_tree_pu([],[],nil).
pre_in_tree_pu([X|PL],IL,t(X,Left,Right)) :-
append(ILeft,[X|IRight],IL),
append(PLeft,PRight,PL),
pre_in_tree_pu(PLeft,ILeft,Left),
pre_in_tree_pu(PRight,IRight,Right).
% 17.d.
pre_in_tree_d(P,I,T) :-
atom_chars(P,PL), atom_chars(I,IL), pre_in_tree_dl(PL-[],IL-[],T).
pre_in_tree_dl(P-P,I-I,nil).
pre_in_tree_dl(P1-P4,I1-I4,t(X,Left,Right)) :-
symbol1(X,P1-P2), symbol1(X,I2-I3),
pre_in_tree_dl(P2-P3,I1-I2,Left),
pre_in_tree_dl(P3-P4,I3-I4,Right).
symbol1(X,[X|Xs]-Xs).
% 18.
dotstring(T,S) :- nonvar(T), !, dots(T,L-[]), atom_chars(S,L).
dotstring(T,S) :- atom(S), atom_chars(S,L), dots(T,L-[]).
dots(nil,L1-L2) :- sy('.',L1-L2).
dots(t(X,Left,Right),L1-L4) :-
letter(X,L1-L2),
dots(Left,L2-L3),
dots(Right,L3-L4).
sy(X,[X|Xs]-Xs).
UNIT TEST
:-begin_tests(testtree).
use_module(tree).
test(istree):-istree(nil).
test(istree):-istree(t(a,nil,nil)).
test(istree,[fail]):-istree(t(a,b,c)).
test(imbang):-imbang(0,nil).
test(imbang):-imbang(1,t(x,nil,nil)).
test(imbang):-imbang(2,t(x,t(x,nil,nil),nil)).
test(imbang,[fail]):- imbang(3,t(x,t(x,t(x,nil,nil),nil),nil)).
test(simetris):-simetris(nil).
test(simetris):-simetris(t(x,nil,nil)).
test(simetris):-simetris(t(x,t(x,nil,nil),t(x,nil,nil))).
test(simetris,[fail]):- simetris(t(x,t(x,t(x,nil,nil),nil),t(x,nil,nil))).
test(construct):- construct([],nil).
test(construct):- construct([2],t(2,nil,nil)).
test(construct):- construct([2,9],t(2,nil,t(9,nil,nil))).
test(construct):-
construct([5,3,7,1,4,9],t(5,t(3,t(1,nil,nil),t(4,nil,nil)),t(7,nil,t(9,nil,nil
)))).
test(construct,[fail]):- construct([1,3,5],t(1,t(3,t(5,nil,nil),nil),nil)).
test(sym_cbal_tree):- sym_cbal_tree(3,t(x,t(x,nil,nil),t(x,nil,nil))).
test(sym_cbal_tree,[fail]):-
sym_cbal_tree(4,t(x,t(x,nil,nil),t(x,nil,t(x,nil,nil)))).
test(hbal_tree):- hbal_tree(0,nil).
test(hbal_tree):- hbal_tree(1,t(x,nil,nil)).
test(hbal_tree):- hbal_tree(2,t(x,t(x,nil,nil),nil)).
test(hbal_tree,[fail]):- hbal_tree(3,t(x,t(x,t(x,nil,nil),nil),nil)).
test(hbal_tree_nodes):- hbal_tree_nodes(0,nil).
test(hbal_tree_nodes):- hbal_tree_nodes(1,t(x,nil,nil)).
test(hbal_tree_nodes):-
hbal_tree_nodes(4,t(x,t(x,t(x,nil,nil),nil),t(x,nil,nil))).
test(hbal_tree_nodes,[fail]):-
hbal_tree_nodes(3,t(x,t(x,nil,t(x,nil,nil)),nil)).
test(daun):- daun(nil,0).
test(daun):- daun(t(x,nil,nil),1).
test(daun):-
daun(t(5,t(3,t(1,nil,nil),t(4,nil,nil)),t(7,nil,t(9,nil,nil))),3).
test(daun,[fail]):- daun(t(x,nil,t(x,nil,t(x,nil,nil))),2).
test(leaves):- leaves(nil,[]).
test(leaves):- leaves(t(a,nil,nil),[a]).
test(leaves):- leaves(t(a,t(b,nil,nil),t(c,nil,nil)),[b,c]).
test(leaves,[fail]):- leaves(t(a,t(b,nil,nil),nil),[a]).
test(internals):-internals(nil,[]).
test(internals):-internals(t(a,nil,nil),[]).
test(internals):-internals(t(a,t(b,nil,nil),t(c,nil,nil)),[a]).
test(internals,[fail]):-internals(t(a,t(b,nil,nil),nil),[b]).
test(atlevel):-atlevel(nil,1,[]).
test(atlevel):-atlevel(t(a,nil,nil),1,[a]).
test(atlevel):-atlevel(t(a,t(b,nil,nil),t(c,nil,nil)),2,[b,c]).
test(atlevel,[fail]):-atlevel(t(a,t(b,nil,nil),t(c,nil,nil)),1,[b,c]).
test(complete_binary_tree):-
complete_binary_tree(3,t(a,t(b,nil,nil),t(c,nil,nil))).
test(complete_binary_tree,[fail]):-
complete_binary_tree(3,t(a,t(b,nil,nil),nil)).
test(layout_binary_tree):-
layout_binary_tree(t(a,t(b,nil,nil),t(c,nil,nil)),t(a,2,1,t(b,1,2,nil,nil),t(c
,3,2,nil,nil))).
test(layout_binary_tree,[fail]):-
layout_binary_tree(t(a,t(b,nil,nil),t(c,nil,nil)),t(a,1,1,t(b,1,2,nil,nil),t(c
,2,2,nil,nil))).
test(layout_binary_tree2):-
layout_binary_tree(t(a,t(b,nil,nil),t(c,nil,nil)),t(a,2,1,t(b,1,2,nil,nil),t(c
,3,2,nil,nil))).
test(layout_binary_tree2,[fail]):-
layout_binary_tree(t(a,t(b,nil,nil),t(c,nil,nil)),t(a,1,1,t(b,1,2,nil,nil),t(c
,2,2,nil,nil))).
test(layout_binary_tree3):-
layout_binary_tree(t(a,t(b,nil,nil),t(c,nil,nil)),t(a,2,1,t(b,1,2,nil,nil),t(c
,3,2,nil,nil))).
test(layout_binary_tree3,[fail]):-
layout_binary_tree(t(a,t(b,nil,nil),t(c,nil,nil)),t(a,1,1,t(b,1,2,nil,nil),t(c
,2,2,nil,nil))).
test(tree_string):-tree_string(nil,'').
test(tree_string):-tree_string(t(a,t(b,nil,nil),t(c,nil,nil)),'a(b,c)').
test(tree_string,[fail]):-tree_string(t(a,t(b,nil,nil),t(c,nil,nil)),'a,b,c').
test(tree_string1):-tree_string(nil,'').
test(tree_string1):-tree_string(t(a,t(b,nil,nil),t(c,nil,nil)),'a(b,c)').
test(tree_string1,[fail]):-
tree_string(t(a,t(b,nil,nil),t(c,nil,nil)),'a,b,c').
test(preorder):-preorder(nil, '').
test(preorder):-preorder(t(a,t(b,nil,nil),t(c,nil,nil)),abc).
test(preorder,[fail]):-preorder(t(a,t(b,nil,nil),t(c,nil,nil)),bac).
test(preorder1):-preorder1(nil, '').
test(preorder1):-preorder1(t(a,t(b,nil,nil),t(c,nil,nil)),abc).
test(preorder1,[fail]):-preorder1(t(a,t(b,nil,nil),t(c,nil,nil)),bac).
test(inorder):-inorder(nil, '').
test(inorder):-inorder(t(a,t(b,nil,nil),t(c,nil,nil)),bac).
test(inorder,[fail]):-inorder(t(a,t(b,nil,nil),t(c,nil,nil)),abc).
test(inorder1):-inorder1(nil, '').
test(inorder1):-inorder1(t(a,t(b,nil,nil),t(c,nil,nil)),bac).
test(inorder1,[fail]):-inorder1(t(a,t(b,nil,nil),t(c,nil,nil)),abc).
test(pre_in_tree):-pre_in_tree(abc,bac,t(a,t(b,nil,nil),t(c,nil,nil))).
test(pre_in_tree,[fail]):-pre_in_tree(bac,cba,t(a,t(b,nil,nil),t(c,nil,nil))).
test(pre_in_tree_d):-pre_in_tree_d(abc,bac,t(a,t(b,nil,nil),t(c,nil,nil))).
test(pre_in_tree_d,[fail]):-
pre_in_tree_d(bac,cba,t(a,t(b,nil,nil),t(c,nil,nil))).
test(dotstring):-dotstring(nil,('.')).
test(dotstring):-dotstring(t(a,nil,nil),('a..')).
test(dotstring):-dotstring(t(a,t(b,nil,nil),t(c,nil,nil)),('ab..c..')).
test(dotstring,[fail]):-dotstring(t(a,t(b,nil,nil),t(c,nil,nil)),('abc.')).
:-end_tests(testtree).