Kurt-kuzu-ot bulmacasıyla ilgili bir yazı yazmıştım. O yazımı tekrar okudum ve bilgilerin yeterince açıklayıcı bir şekilde sunulmadıĝını farkettim.
Declarative kod yazma tarzının anlaşılmasının bir yazılımcı için önemli olduĝunu düşünüyorum, o yüzden Prolog dili ile sıfırdan bir giriş yapma kararı aldım. 3-4 bölümden ibaret olacak ve her bir bölümü bir oturuşta okuyabileceĝiniz uzunlukta. Birinci bölümün sonundaki alıştırmaya gelene kadar arkanıza yaslanıp okumanızı öneriyorum; sonrasında kod yazarak eşlik edebilirsiniz.
O zaman başlayalım…
Bölüm 1 - Basit Kurallar
Öncelikle eĝer başka programlama dillerine (hele de imperative tarzdaki (C, Java, Python, JavaScript)) aşina iseniz Prolog’u bir programlama dili deĝil de bir veritabanı veya bir bilgi-sorgu-sistemi olarak düşünmeniz yardımcı olabilir.
Sisteme önce bir dizi bilgi/kural girecek, sonra da bu kurallar üzerine sorular soracaĝız.
Örneĝin:
Kurallar
meyve(elma).
meyve(armut).
sebze(havuc).
sebze(patates).
Sorgular
| ?- meyve(elma).
yes (1)
| ?- meyve(patates).
no (2)
(1) "elma bir meyve mi" sorusunu sormuşuz. Cevap "yes" (2) bu biçimde bir bilgiyi sistem bulamamış ve "no" cevabını vermiş
Bir adım öteye gidelim: Sisteme evet/hayır sorularından ötesini de sorabiliyoruz. Mesela:
Sorgular
| ?- meyve(X).
X = elma
X = armut
Prolog büyük harfle başlayan bir terimi görünce (mesela X
ya da Birsey
) "acaba ben bunun yerine ne koyabilirim?" diye aranmaya başlar. meyve(X)
şeklindeki kuralları ararsak X
in yerine elma
veya armut
yazınca bunu saĝlayabildiĝimizi farkediyoruz. Sistem de zaten cevap olarak bize 2 adet X deĝerini bulup listelemiş.
meyve(elma)
deyip sonra "elma meyve mi?" diye sormak biraz manasız diye düşünüyorsanız haklısınız. O zaman yazdıĝımızdan ötesini sorgulamaya başlayalım.
kurallar.pl
insan(ali).
insan(veli).
insan(melih).
insan(ayse).
insan(fatma).
sigir(karabas).
sigir(cankiz).
erkek(ali).
erkek(veli).
erkek(melih).
erkek(karabas).
disi(ayse).
disi(fatma).
disi(cankiz).
kadin(X) :- insan(X), disi(X).
adam(X) :- insan(X), erkek(X).
inek(X) :- sigir(X), disi(X). (1)
boga(X) :- sigir(X), erkek(X).
-
inek(X)
kuralı doĝru ise öyle bir X deĝeri vardır kisigir(X)
dogrudur vedisi(X)
de dogrudur. Yani X inek ise o zaman X sıĝırdır ve X dişidir.
Sorgular
| ?- kadin(X).
X = ayse
X = fatma
| ?- boga(X)
X = karabas
Dikkatinizi çekti mi bilmiyorum ama hem ve
hem de veya
işlemlerini gördük şimdiye kadar.
erkek(ali).
erkek(veli).
erkek(melih). (1)
boga(X) :- sigir(X), erkek(X). (2)
-
X = ali
veyaX = veli
veyaX = melih
içinerkek(X)
kuralı doĝrudur. -
bir X deĝeri için
sigir(X)
veerkek(X)
iseboga(X)
doĝrudur.
edepsiz(melih).
okuz(X) :- boga(X).
okuz(X) :- insan(X), edepsiz(X).
Veya kullanımına başka bir örnek. Eĝer X bir boĝa ise veya asansörden inerken kendinden sonraki binecekler için sürpriz osuruklar bırakan Melih adında bir arkadaşımız ise o zaman okuz(X)
doĝrudur. Melih arkadaşım, kahvaltıda çürük yumurta mı yiyorsun, n’apıyorsun anlamıyorum ama bi gastro-entroloĝa görünmende fayda var. Bu koku normal deĝil.
Bölüm 1 - Alıştırma
Kurallar giderek karmaşıklaşacak. Oralara geçmeden biraz pratik yapmak faydalı olabilir.
Ben sizden aile ilişkilerini sorgulayabileceĝimiz kurallar istiyorum. Oldukça klasik bir prolog’a-giriş problemidir: Aşaĝıda yazacaĝınız kod için bir taslak sundum: anne
ve dayi
için de örnek çözümler verdim.
Kendi geniş ailenizdeki (veya bildiĝiniz başka bir ailedeki):
-
erkeklerin kimler olduĝunu yazın.
-
kadınlarin kimler olduĝunu yazın.
-
kimin kimin çocuĝu olduĝunu yazın.
-
anne
vedayi
'yi yazdıĝım gibi diĝer aile ilişkileri için de kurallar yazın.
https://swish.swi-prolog.org/ adresinde çalışan bir prolog makinesi var.
Kuralları ekranın solundaki panele yazıyoruz. Sorguları ise ekranın saĝındaki (?-
simgesi olan) panelden yapıyoruz. Bittikten sonra sistemi sorgulayın. Bir kişinin amcalarının kimler olduĝunu bulabiliyor mu? Kuzenlerinizi doĝruluyor mu?
erkek(?).
erkek(?).
...
disi(?).
disi(?).
...
cocuk(?, ?).
cocuk(?, ?).
...
anne(Anne, Cocuk) :- cocuk(Cocuk, Anne), kadin(Anne).
baba(X, Y) :- ?
dayi(Dayi, Yegen) :- kardes(Dayi, X), evebeyn(X, Yegen), kadin(X).
amca(X, Y) :- ?
kardes(X, Y) :- ?
kuzen(X, Y) :- ?
dede(X, Y) :- ?
babanne(X, Y) :- ?
es(X, Y) :- ?
gorumce(X, Y) :- ?
kaynana(X, Y) :- ?
Yazının ikinci bölümünde aile-ilişkileri problemi için olası bir çözüm verecek ve kendini recursive açan kural tanımlarından bahsederek biraz kafa karıştıracaĝım.
Görüşmek üzere…