Declarative Programlamaya Giriş - 1 / Prolog

October 2021 · 3 minute read

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 Xin 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).
  1. inek(X) kuralı doĝru ise öyle bir X deĝeri vardır ki sigir(X) dogrudur ve disi(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)
  1. X = ali veya X = veli veya X = melih için erkek(X) kuralı doĝrudur.

  2. bir X deĝeri için sigir(X) ve erkek(X) ise boga(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 ve dayi '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…​