Kamis, 10 Desember 2009

Summary Loop

6.1fixed number of times Loop
Banyak bahasa pemrograman menyediakan 'for loop' yang memungkinkan satu set instruksi
akan dieksekusi tetap beberapa kali. fasilitas tersebut tidak tersedia dalam Prolog
, tetapi efek yang sama dapat diperoleh dengan menggunakan rekursi, seperti ditunjukkan dalam
contoh program di bawah ini.

Contoh 1
Keluaran program berikut bilangan bulat dari nilai tertentu sampai 1.
loop(0).
loop(N):-N>0,write('The value is: '),write(N),nl,
M is N-1,loop(M).
Predikat loop didefinisikan dalam istilah itu sendiri. Kalimat kedua dapat
dianggap sebagai: 'untuk loop dari N, pertama menulis nilai N, kemudian kurangi satu untuk memberikan
M, lalu loop dari M '. Proses ini jelas harus dihentikan dan ini
dicapai oleh klausa pertama: 'ketika argumen adalah nol, melakukan apa-apa (dan karenanya
berhenti) '. Klausa pertama dapat dianggap sebagai suatu kondisi untuk menghentikan rekursi.

?- loop(6).
The value is: 6
The value is: 5
The value is: 4
The value is: 3
The value is: 2
The value is: 1
yes

Perhatikan penggunaan dua gol M adalah N-1, loop (M) dalam kalimat kedua untuk
loop predikat. Alternatif yang jelas loop (N-1) tidak akan bekerja. Prolog hanya
mengevaluasi pernyataan seperti N-1 ketika mengevaluasi tujuan dengan atau functor adalah salah satu dari
operator relasional, seperti dijelaskan dalam Bab 4. N-1 jika digunakan sebagai argumen
suatu predikat itu diartikan istilah dengan infiks operator - (yaitu tanda minus) dan
argumen N dan 1. Ini sangat tidak mungkin apa yang dimaksudkan!

Example 2
Program berikutnya keluaran bilangan bulat dari inclusive pertama hingga akhir.
/* output integers from First to Last inclusive */
output_values(Last,Last):- write(Last),nl,
write('end of example'),nl.
output_values(First,Last):-First=\=Last,write(First),
nl,N is First+1,output_values(N,Last).
Disini output_values memiliki 2 argumen yang bisa dibaca sebagai output integer dari inklusif pertama hingga terakhir. Loop berakhir ketika kedua argumen
sama.
?- output_values(5,12).
56789
10
11
12
end of example
yes

6.2 Loop sampai kondisi terpenuhi
Banyak bahasa memiliki sebuah 'for loop' yang memungkinkan sebuah set instruksi yang akan
dieksekusi berulang kali sampai kondisi tertentu terpenuhi. Sekali lagi, tidak ada fasilitas seperti
tersedia secara langsung di Prolog, tetapi efek yang sama dapat diperoleh dengan beberapa cara.

6.2.1 Rekursi
Contoh pertama di bawah ini menunjukkan penggunaan istilah rekursi untuk membaca dimasukkan oleh
pengguna dari keyboard dan output mereka ke layar, sampai selesai.

6.2.2 menggunakan predikat 'repeat'
Meskipun sering dapat digunakan untuk efek yang besar, rekursi tidak selalu yang paling mudah
cara untuk menyediakan jenis perulangan yang diperlukan dalam program Prolog. Metode lain
yang sering digunakan adalah berdasarkan pada built-in predikat ulangi.
Nama predikat ini benar-benar sebuah ironi. Tujuan tidak mengulangi
mengulangi apa pun; itu hanya berhasil setiap kali disebut. Nilai besar mengulang
adalah bahwa hal itu juga berhasil (sebanyak yang diperlukan) pada kemunduran. Efek
ini, seperti untuk tujuan lainnya berhasil, adalah untuk mengubah urutan mengevaluasi tujuan
dari "kanan ke kiri '(yaitu backtracking) kembali ke' kiri-ke-kanan '. Ini dapat digunakan untuk
menciptakan efek perulangan, seperti ditunjukkan pada contoh di bawah ini.
Program ini berulang kali mendorong pengguna untuk memasukkan istilah sampai entah ya atau tidak
dimasukkan. Ini adalah alternatif dari program rekursif ditampilkan di bagian akhir
bagian sebelumnya. Dalam hal ini masih diperdebatkan apakah menggunakan mengulang adalah
perbaikan menggunakan rekursi, tetapi contoh adalah termasuk untuk tujuan
ilustrasi.

6.3 menelusuri kegagalan
Seperti namanya, predikat gagal selalu gagal, apakah pada 'standar'
evaluasi kiri-ke-kanan atau pada kemunduran. Keuntungan dapat diambil dari ini,
dikombinasikan dengan otomatis Prolog backtracking, untuk pencarian melalui database untuk
menemukan semua klausa dengan properti tertentu.

6.3.1 mencari database prolog
Misalkan database berisi klausa seperti
anjing (fido).
anjing (fred).
anjing (jonathan).
Setiap anjing klausul dapat diproses pada gilirannya menggunakan predikat alldogs didefinisikan
di bawah.
alldogs:-anjing (X), write (X), menulis ( 'adalah anjing'), nl, gagal.
alldogs.
Memanggil alldogs akan menyebabkan anjing (X) untuk dicocokkan dengan anjing ayat-ayat dalam
database. Awalnya X akan terikat untuk fido dan "fido adalah anjing 'akan output. Itu
tujuan akhir klausa pertama dari predikat alldogs kemudian akan menyebabkan evaluasi untuk
gagal. Prolog akan mundur atas nl dan dua tujuan menulis (semua yang
unresatisfiable) hingga mencapai anjing (X). Tujuan ini akan berhasil untuk kedua kalinya
menyebabkan X untuk terikat untuk fred.
Proses ini akan berlanjut sampai fido, fred dan jonathan semua telah keluaran,
ketika evaluasi akan kembali gagal. Kali ini panggilan untuk anjing (X) juga akan gagal karena ada
Tidak ada anjing lebih lanjut pasal-pasal dalam database. Hal ini akan menyebabkan klausul pertama untuk
alldogs gagal dan Prolog untuk memeriksa klausul kedua alldogs. Ini
berhasil dan evaluasi akan berhenti.
Efeknya adalah untuk loop melalui database menemukan semua kemungkinan nilai dari X yang
memenuhi tujuan anjing (X).
? - Alldogs.
fido adalah anjing
fred adalah anjing
jonathan adalah anjing
ya
Catatan pentingnya klausa kedua dari alldogs predikat. Hal ini ada untuk
memastikan bahwa, setelah database telah digeledah, tujuan berhasil. Dengan hanya
baris pertama, setiap panggilan ke alldogs akhirnya akan gagal.
alldogs:-anjing (X), write (X), menulis ( 'adalah anjing'), nl, gagal.
? - Alldogs.
fido adalah anjing
fred adalah anjing
jonathan adalah anjing
tidak
Program berikutnya dirancang untuk mencari database yang berisi klausa
mewakili nama, umur, tempat tinggal dan pekerjaan sejumlah
orang-orang.
Jika database berisi lima klausa
orang (john, smith, 45, london, dokter).
orang (martin, williams, 33, Birmingham, guru).
orang (henry, smith, 26, manchester, tukang ledeng).
orang (jane, Wilson, 62, london, guru).
orang (mary, smith, 29, glasgow, surveyor).
Nama semua guru dapat ditemukan dengan menggunakan allteachers predikat.
allteachers:-orang (Forename, Surname ,_,_, guru),
write (Forename), menulis ( ''), menulis (Marga), nl,
gagal.
allteachers.
Efek menggunakan backtracking dengan kegagalan dalam kasus ini adalah untuk menemukan semua
guru dalam database.
? - Allteachers.
martin williams
jane wilson
ya
Jika kedua klausul allteachers dihilangkan, baik guru masih akan
ditemukan tetapi evaluasi allteachers akan berakhir dengan kegagalan. Ini adalah yang sedikit atau
tidak penting ketika tujuan yang dimasukkan pada sistem prompt, tetapi jika allteachers itu
digunakan sebagai tujuan dalam tubuh aturan itu jelas akan mudah untuk dilaksanakan untuk memastikan bahwa
selalu berhasil.
Perlu dicatat bahwa tidak selalu perlu untuk menggunakan 'backtracking dengan
kegagalan 'untuk mencari database. Sebagai contoh, predikat somepeople / 0 didefinisikan
di bawah ini akan menemukan semua orang dalam database yang diberikan sebelumnya, turun ke williams,
standar hanya menggunakan backtracking.
somepeople:-orang (Forename, Marga ,_,_,_),
write (Forename), menulis ( ''), menulis (Marga), nl,
Nama keluarga = williams.
somepeople.
Tujuan Nama Keluarga = williams berhasil jika variabel terikat Nama Keluarga
williams. Jika tidak, itu gagal. Efeknya adalah untuk mencari basis data hingga dan termasuk
orang klausul dengan argumen kedua williams.
? - Somepeople.
John Smith
martin williams
ya

6.3.2 Mencari Solusi berlebih
menelusuri kegagalan juga dapat digunakan untuk mencari semua cara untuk memuaskan tujuan.
Misalkan sebuah predikat findroute (Town1, Town2, Route) menemukan sebuah rute Route
antara dua kota Town1 dan Town2. Rincian predikat ini tidak relevan
di sini. Ini dapat diasumsikan bahwa Town1 dan Town2 adalah atom dan bahwa rute ini adalah daftar.
menelusuri kegagalan kemudian dapat digunakan untuk mencari semua kemungkinan rute antara
Town1 dan Town2 dan menulis masing-masing satu di baris terpisah, sebagai berikut:
find_all_routes (Town1, Town2): --
findroute (Town1, Town2, Route),
write ( 'Kemungkinan rute:'), menulis (Route), nl, gagal.
find_all_routes (_,_).

Tidak ada komentar:

Posting Komentar