Pengendalian Alur
Fail Cut Rekursi
Fail Turbo prolog 2.0 akan melakukan runut balik apabila menemui kondisi gagal (gagal dalam mencari jawaban dari suatu subgoal). Hal ini bisa dilakukan dengan menggunakan predikat standar fail. Predikat fail mempunyai sifat tidak pernah benar Apabila dalam suatu klausa terdapat fail, maka predikat (subgoal) sesudah predikat fail tidak akan pernah dieksekusi oleh Turbo Prolog 2.0.
cut Predikat cut ( ! ) digunakan untuk menghalangi terjadinya runut balik. Predikat cut selalu benar dan bila predikat cut telah dilewati maka tidak akan mungkin untuk melakukan runut balik ke subgoal sebelum predikat cut dalam klausa yang sedang dieksekusi.
Misalkan: Ada 4 buah klausa yang terdiri dari 2 jenis yaitu x dan y. x:- a,b,!,c,d. x:- e. y:- r,x,s. y:- t. Bila kondisi gagal ditemui pada subgoal a atau b, maka Turbo Prolog 2.0 akan dapat melakukan runut balik pada subgoal a atau b. Bila tidak ditemui kemungkinan jawaban yang lain, maka Turbo Prolog 2.0 akan melanjutkan ke klausa x berikutnya yang terdiri dari subgoal e. Bila subgoal a dan b benar, Turbo Prolog 2.0 akan mengeksekusi predikat cut yang selalu benar. Kemudian Turbo Prolog 2.0 melanjutkan ke subgoal c. Bila turbo Prolog 2.0 menemui kondisi gagal, maka Turbo Prolog 2.0 hanya dapat melakukan runut balik pada subgoal c dan tidak dapat melakukan runut balik ke subgoal a, b atau ke x yang lain karena dihalangi oleh predikat cut yang berfungsi sebagai pagar.
Contoh program predikat fail DOMAINS kota, propinsi = string PREDICATES ibu_kota(kota,propinsi) tampil CLAUSES ibu_kota("Surabaya","Jawa Timur"). ibu_kota("Semarang","Jawa Tengah). ibu_kota("Bandung","Jawa Barat"). ibut_kota("Palembang","Sumatera Selatan"). tampil :- ibu_kota(Kota,Propinsi), write(Kota," adalah ibu kota ",Propinsi,"\n"), fail.
Contoh program predikat cut DOMAINS kota, propinsi = string PREDICATES ibu_kota(kota,propinsi) tampil cek(kota) CLAUSES ibu_kota("Surabaya","Jawa Timur"). ibu_kota("Semarang","Jawa Tengah). ibu_kota("Bandung","Jawa Barat"). ibut_kota("Palembang","Sumatera Selatan"). tampil :- ibu_kota(Kota,Propinsi), write(Kota," adalah ibu kota ",Propinsi,"\n"), fail. tampil. cek("Semarang") :-!, cek(_).
Rekursi Dalam bahasa komputer prosedural (Basic, Pascal atau C), rekursi adalah suatu prosedur yang mengandung prosedur itu sendiri. Dalam Turbo Prolog 2.0 didefinisikan sebagai suatu klausa yang salah satu subgoalnya adalah klausa itu sendiri.
Contoh program faktorial DOMAINS angka = integer hasil = real PREDICATES faktorial(angka,hasil) CLAUSES faktorial(1,1) :-!. faktorial(X,FaktY) :- Y = X - 1, faktorial(Y,FaktY), FaktX = X * FaktY.
Rekursi ekor Metode rekursi memiliki suatu kelemahan, yaitu menghabiskan banyak lokasi memori untuk menyimpan stack frame, apalagi bila rekursi harus dilakukan banyak sekali. Memori komputer hanya dapat menampung paling banyak 4000 stack frame. Itu berarti hanya dapat menampung paling banyak 4000 kali pengulangan. Untuk mengatasi masalah ini, digunakan metode rekursi ekor (tail recursion). Pada rekursi ekor, tidak diperlukan lagi penyimpanan informasi di stack frame karena pada waktu memanggil dirinya sendiri, informasi tersebut telah diikutsertakan juga dalam bentuk variabel. Syarat penggunaan metode rekursi ekor: Subgoal yang memanggil dirinya sendiri diletakkan pada bagian akhir klausa tersebut. Tidak ada titik runut balik di dalam klausa tersebut.
program untuk menghasilkan deret dengan pertambahan 1 DOMAINS angka = integer PREDICATES deret(angka) CLAUSES deret(N) :- write(N," "), NN = N + 1, deret(NN).
Penyebab rekursi ekor tidak terjadi Bila subgoal yang memanggil dirinya sendiri tidak terletak di bagian akhir. Contoh : deret(N) :- write(N," "), NN = N + 1, deret(NN), nl.
Bila masih ada klausa yang sama lainnya belum dicoba pada saat rekursi terjadi (terdapat titik runut balik). Contoh : deret2(N) :- write(N," "), NN = N + 1, deret2(NN). N < 0, Write(“ N adalah bilangan negatif”).
Bila di dalam klausa tersebut terdapat subgoal yang mempunyai beberapa alternatif jawaban (yang memungkinkan terjadinya runut balik). deret3(N) :- write(N," "), NN = N + 1, Cek(NN), Deret3(NN). cek(X) :- X >= 0 cek(X):- X < 0
Mengatasi masalah rekursi ekor Masalah yang terjadi pada rekursi ekor yang menyebabkan tidak terjadinya rekursi ekor dapat diatasi dengan menggunakan predikat cut (!). Predikat cut menyebabkan Turbo Prolog 2.0 tidak dapat melakukan runut balik ke subgoal sebelumnya. Dengan demikian Turbo Prolog 2.0 sudah tidak melihat adanya kemungkinan lain yang dapat dicoba sehingga rekursi yang terjadi benar-benar merupakan rekursi ekor yang tidak menghabiskan memori.
program deret3 dapat diperbaiki dengan menambahkan predikat cut deret3(N) :- write(N," "), NN = N + 1, Cek(NN),!, Deret3(NN). cek(X) :- X >= 0 cek(X):- X < 0
program deret2 dapat diperbaiki dengan menambahkan predikat cut deret2(N) :- N >= 0,!, write(N," "), NN = N + 1, deret2(NN). Write(“ N adalah bilangan negatif”).
Program deret menggunakan rekursi ekor DOMAINS angka = integer PREDICATES deret(angka,angka,angka) GOAL makewindow(1,13,9,"REKURSI",5,10,15,60), write(" Program ini akan menghasilkan deret hitung \n"), write("\n Angka awal : "),readint(Awal), write("\n Angka akhir : "),readint(Akhir), write("\n Selang : "),readint(Selang), write("\n\n"), deret(Awal,AKhir,Selang).
CLAUSES deret(AKhir,AKhir,_). deret(Awal,Akhir,Selang) :- write(Awal," "), Bil = Awal + Selang, deret(Bil,AKhir,Selang).
Repeat Predikat repeat digunakan untuk memaksa program agar mencari kemungkinan jawaban yang lain melalui runut balik. Predikat repeat bukanlah predikat jadi sehingga bila kita akan menggunkannya, kita harus mendefinisikanny di dalam program dan kita bisa menggunakan kata sembarang, misalnya ulang, repeat. repeat :- Dengan struktur seperti diatas, program akan selalu mencatat adanya titik runut balik pada klausa tersebut.
Predikat repeat selalu benar Predikat repeat selalu benar. Bila salah satu subgoal dalam suatu klausa yang mengandung predikat repeat mendapatkan kondisi gagal, maka program akan selalu melakukan runut balik ke predikat repeat, setelah runut balik ke subgoal sesudahnya telah selesai dilakukan. Dengan menggunakan predikat repeat, program kita bisa berulang tanpa batas dan biasanya digunakan dalam program yang alurnya selalu kembali ke menu utama.
Program Logon Tidak menggunakan predikat repeat DOMAINS nama,password = symbol PREDICATES logon masukkan_nama(nama,password) pemakai(nama,password) GOAL logon. CLAUSE pemakai(anto,bodor). pemakai(nano,superman). pemakai(toto,aneh).
logon :- makewindow(1,13,2,"LOGON",5,10,10,60), clearwindow, masukkan_nama(_,_), write("Anda diperkenankan menggunakan komputer ini") write("Maaf, password anda tidak tidak termasuk dalam \n"), write("daftar pemakai komputer ini"). masukkan_nama(Nama,Password) :- write("Masukkan Nama Anda = "),readln(Nama),nl, write("Masukkan Password Anda = "),readln(Password), pemakai(Nama,Password).
Program Logon menggunakan predikat repeat DOMAINS nama,password = symbol PREDICATES logon masukkan_nama(nama,password) pemakai(nama,password) repeat GOAL logon. CLAUSE pemakai(anto,bodor). pemakai(nano,superman). pemakai(toto,aneh).
logon :- makewindow(1,13,2,"LOGON",5,10,10,60), clearwindow, masukkan_nama(_,_), write("Anda diperkenankan menggunakan komputer ini"). write("Maaf, password anda tidak tidak termasuk dalam \n"), write("daftar pemakai komputer ini \n"), write("Silahkan Mencoba lagi \n\n"), masukkan_nama(Nama,Password) :- write("Masukkan Nama Anda = "),readln(Nama),nl, write("Masukkan Password Anda = "),readln(Password), pemakai(Nama,Password). repeat. repeat :-