Resume Chapter 6 (LOOPS)

Prolog tidak memiliki fasilitas perulangan, efek yang sama dapat diperoleh yang memungkinkan sesorang urutan tujuan untuk dievaluasi berulang kali. Hal ini dapat dilakukan dalam berbagai
cara, menggunakan backtracking, rekursi, built-in predikat, atau kombinasi dari semuanya.

6.1 Looping a Fixed Number of Times

Banyak bahasa pemrograman menyediakan ‘untuk loop’ yang memungkinkan satu set instruksi
akan dieksekusi tetap beberapa kali. Tidak ada fasilitas tersebut tersedia dalam Prolog
(secara langsung), 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 ke 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: ‘loop dari N, pertama menulis nilai N, kemudian kurangi satu untuk memberikan
M, kemudian 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!

Contoh 2
Program berikutnya keluaran bilangan bulat dari First to Last inklusif.

/* 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).

output_values memiliki dua argumen, yang dapat dibaca sebagai ‘output
bilangan bulat dari First to Last inklusif ‘. Loop berakhir ketika kedua argumen
sama.

?- output_values(5,12).

56789

10

11

12

end of example

yes

Contoh 3

/* sum the integers from 1 to N (the first argument)

inclusive */

sumto(1,1).

sumto(N,S):-N>1,N1 is N-1,sumto(N1,S1),S is S1+N.

?- sumto(100,N).

N = 5050

?- sumto(1,1).

Yes

Perhatikan bahwa menggunakan N1 variabel tambahan untuk menyimpan nilai N-1 adalah
penting. Menulis sumto (N-1, S1), dll bukannya tidak akan bekerja dengan benar. N-1 adalah
istilah, bukan nilai numerik.

Contoh 4
Tentukan sebuah predikat untuk keluaran kuadrat N pertama bilangan bulat, satu per baris.
Ini dapat diprogram paling mudah jika perombakan pertama dalam bentuk rekursif

/* output the first N squares, one per line */

writesquares(1):-write(1),nl.

writesquares(N):-N>1,N1 is N-1,writesquares(N1),

Nsq is N*N,write(Nsq),nl.

?- writesquares(6).

149

16

25

36

yes

6.2 Looping Until a Condition Is Satisfied
Banyak bahasa memiliki ‘setelah 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 Recursion
Contoh pertama di bawah ini menunjukkan penggunaan istilah rekursi untuk membaca
dimasukkan oleh
pengguna dari keyboard dan output mereka ke layar, sampai akhir.

go:-loop(start). /* start is a dummy value used to get

the looping process started.*/

loop(end).

loop(X):-X\=end,write(‘Type end to end’),read(Word),

write(‘Input was ‘),write(Word),nl,loop(Word).

?- go.

Type end to end: university.

Input was university

Type end to end: of.

Input was of

Type end to end: portsmouth.

Input was portsmouth

Type end to end: end.

Input was end

yes

Program rekursif ini berulang kali mendorong pengguna untuk memasukkan istilah sampai baik
ya atau tidak dimasukkan.

get_answer(Ans):-write(‘Enter answer to question’),

nl,get_answer2(Ans).

get_answer2(Ans):-

write(‘answer yes or no’),

read(A),

((valid(A),Ans=A,write(‘Answer is ‘),

write(A),nl);get_answer2(Ans)).

valid(yes). valid(no).

?- get_answer(Myanswer).

Enter answer to question

answer yes or no: maybe.

answer yes or no: possibly.

answer yes or no: yes.

Answer is yes

Myanswer = yes

6.2.2 Using the ‘repeat’ Predicate

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.

get_answer(Ans):-

write(‘Enter answer to question’),nl,

repeat,write(‘answer yes or no’),read(Ans),

valid(Ans),write(‘Answer is ‘),write(Ans),nl.

valid(yes). valid(no).

?- get_answer(X).

Enter answer to question

answer yes or no: unsure.

answer yes or no: possibly.

answer yes or no: no.

answer is no

X = no

Tujuan ke kiri repeat dalam tubuh klausa tidak akan pernah tercapai di backtracking.
Program berikutnya membaca urutan istilah dari file tertentu dan output
mereka ke sungai keluaran sekarang sampai akhir istilah dijumpai.

readterms(Infile):-

seeing(S),see(Infile),

repeat,read(X),write(X),nl,X=end,

seen,see(user).

Program ini menunjukkan bagaimana untuk mengimplementasikan suatu struktur menu yang loop kembali berulang kali untuk meminta lebih banyak masukan. Memasuki pergi pada prompt menyebabkan Prolog untuk output
menu dari mana pengguna dapat memilih satu kegiatan pada satu waktu sampai opsi d adalah
dipilih. Perhatikan bahwa semua input adalah istilah-istilah dan harus diikuti oleh sebuah titik
karakter.

go:- write(‘This shows how a repeated menu works’),

menu.

menu:-nl,write(‘MENU’),nl,

write(‘a. Activity A’),nl,write(‘b. Activity B’),nl,

write(‘c. Activity C’),nl,write(‘d. End’),nl,

read(Choice),nl,choice(Choice).

choice(a):-write(‘Activity A chosen’),menu.

choice(b):-write(‘Activity B chosen’),menu.

choice(c):-write(‘Activity C chosen’),menu.

choice(d):-write(‘Goodbye!’),nl.

choice(_):-write(‘Please try again!’),menu.

?- go.

This shows how a repeated menu works

MENU

a. Activity A

b. Activity B

c. Activity C

d. End

: b.

Activity B chosen

MENU

a. Activity A

b. Activity B

c. Activity C

d. End

: xxx.

Please try again!

MENU

a. Activity A

b. Activity B

c. Activity C

d. End

: d.

Goodbye!

Yes

6.3 Backtracking with Failure
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 Searching the Prolog Database
Misalkan database berisi klausa seperti

dog(fido).

dog(fred).

dog(jonathan).
Setiap dog klausul dapat diproses pada gilirannya menggunakan predikat alldogs didefinisikan
di bawah.

alldogs:-dog(X),write(X),write(‘ is a dog’),nl,fail.

Alldogs.

?- alldogs.

fido is a dog

fred is a dog

jonathan is a dog

yes

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:-dog(X),write(X),write(‘ is a dog’),nl,fail.

?- alldogs.

fido is a dog

fred is a dog

jonathan is a dog

no

Program berikutnya dirancang untuk mencari database yang berisi klausa
mewakili nama, umur, tempat tinggal dan pekerjaan sejumlah
orang-orang.
Jika database berisi lima klausa

person(john,smith,45,london,doctor).

person(martin,williams,33,birmingham,teacher).

person(henry,smith,26,manchester,plumber).

person(jane,wilson,62,london,teacher).

person(mary,smith,29,glasgow,surveyor).

Nama semua guru dapat ditemukan dengan menggunakan allteachers predikat.

allteachers:-person(Forename,Surname,_,_,teacher),

write(Forename),write(‘ ‘),write(Surname),nl,

fail.

Allteachers.

Efek menggunakan backtracking dengan kegagalan dalam kasus ini adalah untuk menemukan semua
guru dalam database

?- allteachers.

martin williams

jane wilson

yes

Jika kedua klausa 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:-person(Forename,Surname,_,_,_),

write(Forename),write(‘ ‘),write(Surname),nl,

Surname=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

yes

6.3.2 Finding Multiple Solutions

Backtracking dengan 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.
Backtracking dengan 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(‘Possible route: ‘),write(Route),nl,fail.

find_all_routes(_,_).

Leave a comment