Declarative Programlamaya Giriş - 3 / Kendi Matematik Sistemimizin İcadı

November 2021 · 4 minute read

Şimdi…​ prolog’da diĝer dillerde olan sayı tanımları (integer, vb) yok deĝil AMA diyelim ki yok…​ Kendi sayı sistemimizi inşaa edebilir miyiz?

Cevap tabii ki evet, yoksa bahsini açmazdım, deĝil mi?

Basitleştirmek adına sadece doĝal sayılar ile ilgilenelim. sıfır sayısını baz alacak ve diĝer sayıları sıfır’a kıyasen yazacaĝız.

Yani:

  • "bir" demek için "sıfır’ın bir arttırılmışı",

  • "iki" demek için "sıfır’ın bir arttırılmışının bir arttırılmışı",

  • "üç" demek için "sıfır’ın bir arttırılmışının bir arttırılmışının bir arttırılmışı",

  • …​

Ben "X’in bir arttırılmışı" demek icin prolog’da bir_arttirilmisi(X) yazacaĝım.

Yani:

  • "bir" demek için bir_arttirilmisi(sifir) ,

  • "iki" demek için bir_arttirilmisi(bir_arttirilmisi(sifir)) ,

  • "üç" demek için bir_arttirilmisi(bir_arttirilmisi(bir_arttirilmisi(sifir))) ,

  • …​

Böyle çok uzun oluyor, bir_arttirilmisi yerine a deyip geçelim.

Yani:

  • "bir" demek için a(sifir) ,

  • "iki" demek için a(a(sifir)) ,

  • "üç" demek için a(a(a(sifir))) ,

  • …​

  • "beş" demek için a(a(a(a(a(sifir))))) ,

  • …​

5 demek için a(a(a(a(a(sifir))))) yazmak garip gelebilir ama şu anda elimizden gelen bu. Bu yapıyı kullanarak bi’kaç kural yazalım: buyuk(X, Y) X’in Y’den büyük olup olmadığını söylesin.

Ama ondan önce ufacık bir şey göstereceĝim. Bir deĝerin dogal sayı olup olmadığını bulalım:

dogalsayi(X)

dogasayi(sifir).
dogalsayi(a(X)) :- dogalsayi(X).   (1)
1 Eger X bir dogal sayı ise X+1 de bir doĝal sayıdır. Yani X+1 ancak ve ancak X bir doĝal sayı ise doĝal sayıdır.

Mesela 3’un bir doĝal sayı olup olmadığına bakalım.

3’u temsilen a(a(a(sifir))) diyoruz.

dogalsayi( a(a(a(sifir))) ) eĝer dogalsayi( a(a(sifir)) ) ise doĝrudur. dogalsayi( a(a(sifir)) ) eĝer dogalsayi( a(sifir) ) ise doĝrudur. dogalsayi( a(sifir) ) eĝer dogalsayi( sifir ) ise doĝrudur. dogalsayi( sifir ) in dogru oldugunu zaten biliyoruz.

O zaman dogalsayi(a(a(a(sifir)))) doĝrudur.

Farkederseniz x :- y biçimindeki bir kuralı "eĝer 'y' ise 'x' doĝrudur" şeklinde okuduk. Yani x :- y demek (lisedeki mantık derslerini hatırlarsanız) y → x yani y ise x yani y doĝru ise x de doĝrudur demek.

:- sembolünü olarak hayal edebilirsiniz.

buyuk(X, Y)

Şimdi buyuk(X, Y) kuralına geri dönelim. X deĝeri Y’den büyük ise buyuk(X,Y) doĝru olsun.

buyuk(a(_), sifir). (1)
buyuk(a(X), a(Y)) :- buyuk(X, Y). (2)

kucuk(X, Y) :- buyuk(Y, X).
1 sıfır dışındaki tüm sayılar sıfır’dan büyüktür
2 X>Y demek için X-1>Y-1 de diyebilmeliyiz. Bu kuralın deĝerleri nasıl faydalı bir şekilde erittiĝini şimdi vereceĝim örnekte göstereceĝim

5 > 3 müdür?

buyuk(a(X), a(Y)) :- buyuk(X, Y) kuralını kullanalım:

5>3 ← 4>2 : 5’in 3’ten büyük olup olmadığını bilmiyorum ama eĝer 4>2 ise 5>3’tür. 4>2 ← 3>1 : 4’ün 2’den büyük olup olmadığını bilmiyorum ama eĝer 3>2 ise 4>2’tür. 3>1 ← 2>0 : 3’ün 1’den büyük olup olmadığını bilmiyorum ama eĝer 2>0 ise 3>2’tür. 2>0 : 1’nci kural bunu söylüyor.

Sisteme 5>3’u sorarsam:

?- buyuk(a(a(a(a(a(sifir))))), a(a(a(sifir)))).

YES

toplam(Z, X, Y)

Devam edelim. `toplam(Z, X, Y)`yi yazalim; Z=X+Y ise dogru olsun.

Yaklaşım olarak buyuk(X, Y)'nin çözümünde a(_) tipindeki bir deĝerin sıfırdan büyük olduğunu kullanmamız gibi, ispatı basit bir doĝru tanımlayıp kalanları onun üzerine inşaa edeceĝiz.

ispatı daha basit bir doĝru
Z = X + Y

Y = 0 ise
  Z = X + 0
  Z = X

yani:

toplam(X, X, sifir).

buyuk(X, Y) kuralını yazarken de buyuk(X, 0) kuralına dayanmıştık. Yaklaşım aynı; ispatı zor olan bir kuralı ispatı kolay olan bir kurala indirgeyecek şekilde yazıyoruz. Sıfır deĝerinin işlemi nasıl etkilediĝini göz önünde bulundurarak kuralı inşaa ediyoruz. Ondan sonra da elimizdeki deĝerleri sıfıra indirgemenin yolunu ariyoruz

Z = X + Y
  = (X+Y) + (Y-Y)
  = (X+Y) + 0

yani

toplam(X, X, sifir).
toplam(Z, X, a(Y)) :- toplam(Z, a(X), Y).
3+2’yi sorgulayalım
toplam(Z, a(a(a(sifir))), a(a(sifir)))

Z = a(a(a(a(a(sifir)))))

3 + 2 'nin cevabi 5 imiş.

Diĝer Aritmetik İşlemler

çıkarma, bölme, çarpma
% cikar(Z, X, Y) demek Z=X-Y demek olsun
cikar(X, X, sifir).
cikar(Z, a(X), a(Y)) :- cikar(Z, X, Y).

% bolum(Z, K, X, Y) demek X'in Y'ye bolumu Z edip kalani K olsun: X = Z*Y + K
bolum(sifir, X, X, Y) :- kucuk(X, Y). (1)
bolum(a(Z), K, X, Y) :- bolum(Z, K, X_, Y), cikar(X_, X, Y). (2)

carpim(sifir, X, sifir).
carpim(Z, X, a(Y)) :- carpim(Z_, X, Y), cikar(Z_, Z, X).
1 eĝer X<Y ise X/Y=0’dir ve kalan X’tir.
2 X > Y ise X / Y = Z demek (X-Y) / Y = Z - 1 demektir. 2’nci kuralı X<Y olana kadar uygulayacagiz. O durumda zaten bolüm’ün de kalan’ın da ne olduğunu biliyoruz çünkü

Guzel degil mi? Kendi sayı sistemimizi inşaa ettik ve onun üzerinde cebir yapiyoruz!

Devamı;

Bir sonraki prolog yazısında kendi sayı sistemimizden onluk sayı sistemine geçmenin yolunu arayacaĝız…​

Görüşmek üzere…​