<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://sonsuzus.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://sonsuzus.github.io/" rel="alternate" type="text/html" /><updated>2026-07-19T12:18:22+00:00</updated><id>https://sonsuzus.github.io/feed.xml</id><title type="html">SonsuzUs</title><subtitle>Programlama ve Yazılım</subtitle><author><name>Sonsuz Us</name></author><entry><title type="html">Geriye İzleme (Backtracking): Çıkmaz Sokaklardan Zekice Dönmek</title><link href="https://sonsuzus.github.io/posts/geriye-izleme-backtracking-cikmaz-sokaklardan-zekice-donmek/" rel="alternate" type="text/html" title="Geriye İzleme (Backtracking): Çıkmaz Sokaklardan Zekice Dönmek" /><published>2026-07-19T00:00:00+00:00</published><updated>2026-07-19T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/geriye-izleme-backtracking-cikmaz-sokaklardan-zekice-donmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/geriye-izleme-backtracking-cikmaz-sokaklardan-zekice-donmek/"><![CDATA[<p>Bir labirentte yürüdüğünü düşün: Önünde üç yol var, birini seçiyorsun, ilerliyorsun ve duvara çarpıyorsun. Panik yok! Son karar noktasına geri dönüp denenmemiş diğer yolu seçiyorsun. İşte geriye izleme, yani backtracking, bilgisayarın bu “hmm olmadı, başka kapı deneyelim” refleksidir. Özellikle bulmaca çözme, rota arama, kombinasyon üretme ve kısıt sağlama problemlerinde sistematik şekilde alternatifleri dener.
``
Backtracking’in kalbinde “seç, ilerle, kontrol et, gerekirse geri al” döngüsü vardır. Algoritma bir çözüm adayını parça parça inşa eder. Her adımda mevcut durumun hedefe götürme ihtimali kontrol edilir. Eğer durum kurallara aykırıysa veya artık çözüm üretme şansı yoksa, algoritma o dalı terk eder. Buna budama (pruning) denir. Budama, gereksiz yolları erkenden keserek aramayı hızlandırır.</p>

<p>Teorik olarak backtracking, derinlik öncelikli arama (DFS) mantığına çok benzer. Fakat klasik DFS sadece graf üzerinde dolaşırken, backtracking genellikle “karar ağacı” üzerinde aday çözümler üretir. Her düğüm bir kısmi çözümü, her kenar ise yeni bir seçimi temsil eder. Eğer dallanma faktörü $b$ ve maksimum derinlik $d$ ise kaba kuvvetle arama maliyeti yaklaşık $O(b^d)$ olabilir. Bu yüzden akıllı kontrol fonksiyonları çok önemlidir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Ne Anlama Gelir?</th>
      <th>Backtracking’de Rolü</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Durum</td>
      <td>O ana kadar yapılan seçimler</td>
      <td>Kısmi çözümü temsil eder</td>
    </tr>
    <tr>
      <td>Seçenek</td>
      <td>Bir sonraki hamle</td>
      <td>Yeni dallar oluşturur</td>
    </tr>
    <tr>
      <td>Kısıt</td>
      <td>Uyulması gereken kural</td>
      <td>Geçersiz yolları eler</td>
    </tr>
    <tr>
      <td>Geri alma</td>
      <td>Son seçimi iptal etme</td>
      <td>Alternatifleri denemeyi sağlar</td>
    </tr>
    <tr>
      <td>Budama</td>
      <td>Umutsuz dalı kesme</td>
      <td>Performansı artırır</td>
    </tr>
  </tbody>
</table>

<p>Basit bir formül gibi düşünürsek algoritmanın davranışı şöyle özetlenebilir: $Çözüm = Seçim + Kısıt\ Kontrolü + Geri\ Alma$. Yani yalnızca denemek değil, denediğini akıllıca geri sarmak önemlidir. Bu yüzden backtracking, “kaba kuvvetin gözlük takmış hali” olarak düşünülebilir.</p>

<p>En meşhur örneklerden biri N-Queens problemidir. Ama daha basit bir örnekle başlayalım: Verilen sayılardan toplamı hedef değere eşit olan bir alt küme bulmak. Aşağıdaki Python kodu, her sayıyı “al” veya “alma” kararlarıyla ilerler; çıkmaza girince önceki adıma döner.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">subset_sum</span><span class="p">(</span><span class="n">nums</span><span class="p">,</span> <span class="n">target</span><span class="p">):</span>
    <span class="n">result</span> <span class="o">=</span> <span class="p">[]</span>

    <span class="k">def</span> <span class="nf">backtrack</span><span class="p">(</span><span class="n">index</span><span class="p">,</span> <span class="n">current</span><span class="p">,</span> <span class="n">total</span><span class="p">):</span>
        <span class="c1"># Hedefe ulaşıldıysa çözümü kaydet
</span>        <span class="k">if</span> <span class="n">total</span> <span class="o">==</span> <span class="n">target</span><span class="p">:</span>
            <span class="n">result</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">current</span><span class="p">.</span><span class="nf">copy</span><span class="p">())</span>
            <span class="k">return</span>

        <span class="c1"># Liste bitti veya toplam hedefi geçtiyse bu dalı bırak
</span>        <span class="k">if</span> <span class="n">index</span> <span class="o">==</span> <span class="nf">len</span><span class="p">(</span><span class="n">nums</span><span class="p">)</span> <span class="ow">or</span> <span class="n">total</span> <span class="o">&gt;</span> <span class="n">target</span><span class="p">:</span>
            <span class="k">return</span>

        <span class="c1"># 1. seçenek: mevcut sayıyı al
</span>        <span class="n">current</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">nums</span><span class="p">[</span><span class="n">index</span><span class="p">])</span>
        <span class="nf">backtrack</span><span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span><span class="p">,</span> <span class="n">total</span> <span class="o">+</span> <span class="n">nums</span><span class="p">[</span><span class="n">index</span><span class="p">])</span>

        <span class="c1"># Geri alma: son eklenen sayıyı çıkar
</span>        <span class="n">current</span><span class="p">.</span><span class="nf">pop</span><span class="p">()</span>

        <span class="c1"># 2. seçenek: mevcut sayıyı alma
</span>        <span class="nf">backtrack</span><span class="p">(</span><span class="n">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="n">current</span><span class="p">,</span> <span class="n">total</span><span class="p">)</span>

    <span class="nf">backtrack</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="p">[],</span> <span class="mi">0</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">result</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">subset_sum</span><span class="p">([</span><span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">7</span><span class="p">],</span> <span class="mi">10</span><span class="p">))</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">current.append(...)</code> bir karar vermektir. <code class="language-plaintext highlighter-rouge">current.pop()</code> ise o kararı geri almaktır. Bu ikili, backtracking’in sahnedeki dansıdır: bir adım ileri, gerekirse bir adım geri. Eğer <code class="language-plaintext highlighter-rouge">total &gt; target</code> olursa algoritma o yolu sürdürmez; çünkü pozitif sayılarla hedefe geri inme şansı yoktur. İşte bu küçük kontrol ciddi performans kazandırır.</p>

<p>Backtracking ile dinamik programlama sık karıştırılır. İkisi de “zor problemi küçük parçalara bölme” fikrini sever, ama yaklaşımları farklıdır.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Backtracking</th>
      <th>Dinamik Programlama</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel fikir</td>
      <td>Alternatifleri dene, geçersizse geri dön</td>
      <td>Alt problemlerin sonuçlarını sakla</td>
    </tr>
    <tr>
      <td>Kullanım</td>
      <td>Kombinasyon, permütasyon, bulmaca</td>
      <td>Optimizasyon, tekrar eden alt problemler</td>
    </tr>
    <tr>
      <td>Bellek kullanımı</td>
      <td>Genellikle daha düşük</td>
      <td>Tablo nedeniyle daha yüksek olabilir</td>
    </tr>
    <tr>
      <td>Performans</td>
      <td>Budamaya çok bağlı</td>
      <td>Tekrarları önlediği için düzenli</td>
    </tr>
  </tbody>
</table>

<p>Backtracking’in kullanıldığı popüler alanlar arasında Sudoku çözümü, 8 vezir problemi, labirent rotası bulma, şifre kombinasyonu denemeleri, graf renklendirme ve kısıt tatmin problemleri vardır. Mesela Sudoku’da her boş hücreye 1’den 9’a kadar sayı denenir; satır, sütun veya kutu kuralı bozulursa sayı geri alınır. Bilgisayar sabırlı bir bulmaca çözücüye dönüşür.</p>

<p>Elbette backtracking her derde deva değildir. Seçenek sayısı çok büyükse ve iyi budama yoksa algoritma yavaşlayabilir. Bu durumda sezgisel sıralama, erken kontrol, memoization veya problemi matematiksel olarak daraltma gibi teknikler eklenir. Örneğin önce en kısıtlı hücreyi seçmek, Sudoku’da arama ağacını dramatik şekilde küçültebilir.</p>

<p>Sonuç olarak geriye izleme, yazılım dünyasının “denedim, olmadı, akıllıca geri döndüm” stratejisidir. Onu güçlü yapan şey sadece tüm yolları denemesi değil; yanlış yollardan zamanında vazgeçmesidir. Eğer bir problem “bir sürü ihtimal var ama kurallar geçersizleri elememi sağlıyor” diyorsa, backtracking büyük ihtimalle kapıda bekleyen kahramandır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="algoritma" /><category term="backtracking" /><category term="veri-yapıları" /><summary type="html"><![CDATA[Bir labirentte yürüdüğünü düşün: Önünde üç yol var, birini seçiyorsun, ilerliyorsun ve duvara çarpıyorsun. Panik yok! Son karar noktasına geri dönüp denenmemiş diğer yolu seçiyorsun. İşte geriye izleme, yani backtracking, bilgisayarın bu “hmm olmadı, başka kapı deneyelim” refleksidir. Özellikle bulmaca çözme, rota arama, kombinasyon üretme ve kısıt sağlama problemlerinde sistematik şekilde alternatifleri dener.]]></summary></entry><entry><title type="html">Listeler ve Veri Yapıları: Head-Tail Mantığını Anlamak</title><link href="https://sonsuzus.github.io/posts/listeler-ve-veri-yapilari-head-tail-mantigini-anlamak/" rel="alternate" type="text/html" title="Listeler ve Veri Yapıları: Head-Tail Mantığını Anlamak" /><published>2026-07-19T00:00:00+00:00</published><updated>2026-07-19T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/listeler-ve-veri-yapilari-head-tail-mantigini-anlamak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/listeler-ve-veri-yapilari-head-tail-mantigini-anlamak/"><![CDATA[<p>Birden fazla veriyi tek tek değişkenlerde taşımak, market poşetlerini tek parmakla taşımaya benzer: mümkün ama gereksiz acı verici. Listeler, verileri köşeli parantezler içinde tek bir bütün gibi saklamamızı sağlar: <code class="language-plaintext highlighter-rouge">[10, 20, 30]</code>. Daha önemlisi, bu bütünün ilk elemanını <strong>baş</strong> yani <strong>head</strong>, geri kalan kısmını ise <strong>kuyruk</strong> yani <strong>tail</strong> olarak düşünebiliriz.
``
Liste dediğimiz yapı, temelde sıralı bir koleksiyondur. Yani elemanların yalnızca varlığı değil, <strong>hangi sırada durdukları</strong> da önemlidir. Matematiksel olarak bir listeyi şöyle düşünebiliriz: $L = [x_1, x_2, x_3, …, x_n]$. Burada listenin uzunluğu $n$ ile gösterilir. Eğer $n = 0$ ise elimizde boş liste vardır: <code class="language-plaintext highlighter-rouge">[]</code>. Eğer $n &gt; 0$ ise listenin başı $x_1$, kuyruğu ise <code class="language-plaintext highlighter-rouge">[x_2, x_3, ..., x_n]</code> olur.</p>

<p>Bu ayrım özellikle fonksiyonel programlamada çok güçlüdür. Çünkü bir listeyi işlemek için genellikle şu soru sorulur: “Liste boş mu?” Boş değilse, baş elemanı alırız ve geri kalan kuyruk üzerinde aynı işlemi tekrarlarız. Bu yaklaşım, özyineleme yani recursion mantığının da temel taşlarından biridir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Anlamı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Liste</td>
      <td>Sıralı veri koleksiyonu</td>
      <td><code class="language-plaintext highlighter-rouge">[3, 5, 8]</code></td>
    </tr>
    <tr>
      <td>Head</td>
      <td>İlk eleman</td>
      <td><code class="language-plaintext highlighter-rouge">3</code></td>
    </tr>
    <tr>
      <td>Tail</td>
      <td>İlk eleman dışındaki liste</td>
      <td><code class="language-plaintext highlighter-rouge">[5, 8]</code></td>
    </tr>
    <tr>
      <td>Boş liste</td>
      <td>Elemanı olmayan liste</td>
      <td><code class="language-plaintext highlighter-rouge">[]</code></td>
    </tr>
  </tbody>
</table>

<p>Klasik dizilerle listeler çoğu dilde birbirine benzer görünür, fakat düşünme biçimi farklı olabilir. Özellikle head-tail yaklaşımı, listeyi parçalara ayırarak anlamayı kolaylaştırır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Odak Noktası</th>
      <th>Tipik Kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İndeks tabanlı</td>
      <td><code class="language-plaintext highlighter-rouge">liste[0]</code>, <code class="language-plaintext highlighter-rouge">liste[1]</code> gibi erişim</td>
      <td>Döngüler, rastgele erişim</td>
    </tr>
    <tr>
      <td>Head-tail tabanlı</td>
      <td>İlk eleman + kalan liste</td>
      <td>Özyineleme, veri ayrıştırma</td>
    </tr>
    <tr>
      <td>Yığın mantığı</td>
      <td>Son giren ilk çıkar</td>
      <td>Undo sistemi, çağrı yığını</td>
    </tr>
    <tr>
      <td>Kuyruk mantığı</td>
      <td>İlk giren ilk çıkar</td>
      <td>Mesaj sırası, görev planlama</td>
    </tr>
  </tbody>
</table>

<p>Python’da köşeli parantezlerle liste oluşturmak oldukça basittir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">sayilar</span> <span class="o">=</span> <span class="p">[</span><span class="mi">4</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">11</span><span class="p">,</span> <span class="mi">18</span><span class="p">]</span>

<span class="n">head</span> <span class="o">=</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
<span class="n">tail</span> <span class="o">=</span> <span class="n">sayilar</span><span class="p">[</span><span class="mi">1</span><span class="p">:]</span>

<span class="nf">print</span><span class="p">(</span><span class="n">head</span><span class="p">)</span>  <span class="c1"># 4
</span><span class="nf">print</span><span class="p">(</span><span class="n">tail</span><span class="p">)</span>  <span class="c1"># [7, 11, 18]
</span></code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">sayilar[0]</code> listenin ilk elemanını verir. <code class="language-plaintext highlighter-rouge">sayilar[1:]</code> ise bir dilimleme işlemidir ve birinci indeksten sona kadar olan kısmı yeni bir liste olarak döndürür. Yani elimizdeki listeyi “ilk lokma” ve “tabakta kalanlar” diye ayırmış oluruz.</p>

<p>Python’da daha zarif bir ayrıştırma yöntemi de vardır:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">meyveler</span> <span class="o">=</span> <span class="p">[</span><span class="sh">'</span><span class="s">elma</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">armut</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">kiraz</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">muz</span><span class="sh">'</span><span class="p">]</span>

<span class="n">head</span><span class="p">,</span> <span class="o">*</span><span class="n">tail</span> <span class="o">=</span> <span class="n">meyveler</span>

<span class="nf">print</span><span class="p">(</span><span class="n">head</span><span class="p">)</span>  <span class="c1"># elma
</span><span class="nf">print</span><span class="p">(</span><span class="n">tail</span><span class="p">)</span>  <span class="c1"># ['armut', 'kiraz', 'muz']
</span></code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">*tail</code> ifadesi, geri kalan tüm elemanları toplar. Kodun yaptığı şey şudur: “İlk elemanı <code class="language-plaintext highlighter-rouge">head</code> değişkenine koy, kalanları da <code class="language-plaintext highlighter-rouge">tail</code> listesi olarak sakla.” Bu, head-tail mantığını doğrudan ifade ettiği için okunması da oldukça rahattır.</p>

<p>Ancak dikkat: boş liste üzerinde head almaya çalışmak hataya yol açar. Çünkü $L = []$ iken $x_1$ diye bir eleman yoktur. Bu yüzden güvenli işlem yapmak için önce listenin boş olup olmadığı kontrol edilmelidir.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">listeyi_yaz</span><span class="p">(</span><span class="n">liste</span><span class="p">):</span>
    <span class="k">if</span> <span class="ow">not</span> <span class="n">liste</span><span class="p">:</span>
        <span class="k">return</span>

    <span class="n">head</span><span class="p">,</span> <span class="o">*</span><span class="n">tail</span> <span class="o">=</span> <span class="n">liste</span>
    <span class="nf">print</span><span class="p">(</span><span class="sh">'</span><span class="s">Baş:</span><span class="sh">'</span><span class="p">,</span> <span class="n">head</span><span class="p">)</span>
    <span class="nf">listeyi_yaz</span><span class="p">(</span><span class="n">tail</span><span class="p">)</span>

<span class="nf">listeyi_yaz</span><span class="p">([</span><span class="mi">10</span><span class="p">,</span> <span class="mi">20</span><span class="p">,</span> <span class="mi">30</span><span class="p">])</span>
</code></pre></div></div>

<p>Bu örnekte fonksiyon önce listenin boş olup olmadığını kontrol eder. Boş değilse baş elemanı yazdırır ve kuyruğu aynı fonksiyona tekrar gönderir. Böylece liste adım adım küçülür. Her adımda problem boyutu $n$ değerinden $n - 1$ değerine iner. Bu da algoritmanın doğal bir sonlanma noktasına sahip olmasını sağlar.</p>

<p>Performans açısından da düşünmek önemlidir. Bir listenin ilk elemanına erişmek çoğu modern dilde $O(1)$ kabul edilir. Fakat <code class="language-plaintext highlighter-rouge">liste[1:]</code> gibi kuyruk üretmek bazı dillerde yeni liste oluşturduğu için $O(n)$ maliyetli olabilir. Bu yüzden teoriyi bilmek güzel, ama kullandığın dilin veri yapısı davranışlarını bilmek daha da güzeldir.</p>

<p>Sonuç olarak listeler yalnızca “yan yana yazılmış değerler” değildir. Onlar, veriyi sıraya koymanın, parçalamanın ve anlamlı biçimde işlemenin temel araçlarındandır. Head-tail mantığı ise bu araç kutusundaki İsviçre çakısı gibidir: basit görünür, ama doğru yerde kullanıldığında kodu hem sadeleştirir hem de düşünme biçimini keskinleştirir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="listeler" /><category term="veri-yapıları" /><category term="programlama-temelleri" /><summary type="html"><![CDATA[Birden fazla veriyi tek tek değişkenlerde taşımak, market poşetlerini tek parmakla taşımaya benzer: mümkün ama gereksiz acı verici. Listeler, verileri köşeli parantezler içinde tek bir bütün gibi saklamamızı sağlar: [10, 20, 30]. Daha önemlisi, bu bütünün ilk elemanını baş yani head, geri kalan kısmını ise kuyruk yani tail olarak düşünebiliriz.]]></summary></entry><entry><title type="html">Mantıksal Karşılaştırma İşlemleri: Karar Mekanizmasının Dedektifleri</title><link href="https://sonsuzus.github.io/posts/mantiksal-karsilastirma-islemleri-karar-mekanizmasinin-dedektifleri/" rel="alternate" type="text/html" title="Mantıksal Karşılaştırma İşlemleri: Karar Mekanizmasının Dedektifleri" /><published>2026-07-19T00:00:00+00:00</published><updated>2026-07-19T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/mantiksal-karsilastirma-islemleri-karar-mekanizmasinin-dedektifleri</id><content type="html" xml:base="https://sonsuzus.github.io/posts/mantiksal-karsilastirma-islemleri-karar-mekanizmasinin-dedektifleri/"><![CDATA[<p>Programlamada bir uygulamanın “akıllı” görünmesini sağlayan şey çoğu zaman çok basit bir sorudur: “Bu doğru mu, değil mi?” Mantıksal karşılaştırma işlemleri; değişkenler veya sabit değerler arasında büyüklük, küçüklük, eşitlik ya da denklik gibi ilişkileri kontrol eder ve sonucu genellikle <code class="language-plaintext highlighter-rouge">true</code> veya <code class="language-plaintext highlighter-rouge">false</code> olarak üretir. Yani kod dünyasının trafik lambaları gibidirler: geç, dur, bekle!</p>

<p>``</p>

<h2 id="karşılaştırma-operatörü-nedir">Karşılaştırma Operatörü Nedir?</h2>

<p>Karşılaştırma operatörleri iki değeri yan yana koyup aralarındaki ilişkiyi test eder. Matematiksel olarak bunu bir önerme gibi düşünebiliriz. Örneğin $x = 10$ ve $y = 7$ ise $x &gt; y$ önermesi doğrudur. Programlama dilinde bu ifade çoğunlukla <code class="language-plaintext highlighter-rouge">true</code> sonucunu verir.</p>

<p>Temel mantık şudur:</p>

\[karşılaştırma(a, b) \rightarrow \{true, false\}\]

<p>Yani iki değer girer, mantıksal bir sonuç çıkar. Bu sonuç daha sonra <code class="language-plaintext highlighter-rouge">if</code>, <code class="language-plaintext highlighter-rouge">while</code>, <code class="language-plaintext highlighter-rouge">for</code>, <code class="language-plaintext highlighter-rouge">switch</code> veya filtreleme gibi karar mekanizmalarında kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>Anlamı</th>
      <th>Örnek</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&gt;</code></td>
      <td>büyüktür</td>
      <td><code class="language-plaintext highlighter-rouge">10 &gt; 5</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;</code></td>
      <td>küçüktür</td>
      <td><code class="language-plaintext highlighter-rouge">3 &lt; 1</code></td>
      <td><code class="language-plaintext highlighter-rouge">false</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&gt;=</code></td>
      <td>büyük veya eşittir</td>
      <td><code class="language-plaintext highlighter-rouge">18 &gt;= 18</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">&lt;=</code></td>
      <td>küçük veya eşittir</td>
      <td><code class="language-plaintext highlighter-rouge">7 &lt;= 4</code></td>
      <td><code class="language-plaintext highlighter-rouge">false</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">==</code></td>
      <td>eşitlik kontrolü</td>
      <td><code class="language-plaintext highlighter-rouge">5 == '5'</code></td>
      <td>dile göre değişir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">===</code></td>
      <td>tip dahil denklik</td>
      <td><code class="language-plaintext highlighter-rouge">5 === '5'</code></td>
      <td><code class="language-plaintext highlighter-rouge">false</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">!=</code></td>
      <td>eşit değildir</td>
      <td><code class="language-plaintext highlighter-rouge">8 != 9</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">!==</code></td>
      <td>tip dahil farklıdır</td>
      <td><code class="language-plaintext highlighter-rouge">8 !== '8'</code></td>
      <td><code class="language-plaintext highlighter-rouge">true</code></td>
    </tr>
  </tbody>
</table>

<h2 id="eşitlik-ve-denklik-aynı-şey-mi">Eşitlik ve Denklik Aynı Şey mi?</h2>

<p>Burada eğlenceli bir tuzak var: “eşit” olmak ile “aynı türden ve aynı değer” olmak her zaman aynı değildir. Özellikle JavaScript gibi dillerde <code class="language-plaintext highlighter-rouge">==</code> değeri karşılaştırırken tür dönüşümü yapabilir. <code class="language-plaintext highlighter-rouge">===</code> ise daha disiplinlidir; hem değerin hem de tipin aynı olmasını ister.</p>

<table>
  <thead>
    <tr>
      <th>İfade</th>
      <th>Açıklama</th>
      <th>Mantıksal Yorum</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">5 == '5'</code></td>
      <td>sayı ve metin karşılaştırılır, dönüşüm olabilir</td>
      <td>gevşek eşitlik</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">5 === '5'</code></td>
      <td>sayı ve metin farklı tiptedir</td>
      <td>sıkı denklik</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0 == false</code></td>
      <td>bazı dillerde <code class="language-plaintext highlighter-rouge">0</code>, <code class="language-plaintext highlighter-rouge">false</code> gibi yorumlanabilir</td>
      <td>dikkat ister</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">0 === false</code></td>
      <td>tipler farklıdır</td>
      <td>daha güvenlidir</td>
    </tr>
  </tbody>
</table>

<p>Bu yüzden karar mekanizması yazarken “Ben sadece değer mi kontrol ediyorum, yoksa tip de önemli mi?” sorusu kritik hale gelir.</p>

<h2 id="karar-mekanizmasına-dahil-etmek">Karar Mekanizmasına Dahil Etmek</h2>

<p>Karşılaştırmalar tek başına test yapar; asıl güçleri karar yapılarıyla birleşince ortaya çıkar. Mesela bir kullanıcının sisteme giriş yapıp yapamayacağını düşünelim. Yaşı yeterli mi? Hesabı aktif mi? Deneme hakkı kaldı mı?</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">yas</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">hesapAktif</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">denemeHakki</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>

<span class="k">if </span><span class="p">(</span><span class="nx">yas</span> <span class="o">&gt;=</span> <span class="mi">18</span> <span class="o">&amp;&amp;</span> <span class="nx">hesapAktif</span> <span class="o">===</span> <span class="kc">true</span> <span class="o">&amp;&amp;</span> <span class="nx">denemeHakki</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Giriş izni verildi.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
  <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Giriş reddedildi.</span><span class="dl">'</span><span class="p">);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu kodda üç farklı karşılaştırma vardır. <code class="language-plaintext highlighter-rouge">yas &gt;= 18</code> kullanıcının reşit olup olmadığını kontrol eder. <code class="language-plaintext highlighter-rouge">hesapAktif === true</code> hesabın gerçekten aktif olup olmadığını tip güvenli biçimde denetler. <code class="language-plaintext highlighter-rouge">denemeHakki &gt; 0</code> ise kullanıcının hâlâ giriş denemesi yapabileceğini gösterir. <code class="language-plaintext highlighter-rouge">&amp;&amp;</code> operatörü ise tüm koşulların doğru olmasını ister.</p>

<p>Mantıksal olarak bunu şöyle yazabiliriz:</p>

\[izin = (yas \ge 18) \land (hesapAktif = true) \land (denemeHakki &gt; 0)\]

<p>Eğer bu üç parçadan biri bile <code class="language-plaintext highlighter-rouge">false</code> olursa genel karar da <code class="language-plaintext highlighter-rouge">false</code> olur.</p>

<h2 id="karşılaştırmalar-sadece-sayılar-i̇çin-değildir">Karşılaştırmalar Sadece Sayılar İçin Değildir</h2>

<p>Karşılaştırma deyince akla hemen sayılar gelse de metinler, tarihler, boole değerler ve nesneler de karşılaştırılabilir. Ancak her veri türünün kuralları farklıdır. Metinlerde alfabetik sıralama, tarihlerde zaman damgası, nesnelerde ise referans karşılaştırması devreye girebilir.</p>

<table>
  <thead>
    <tr>
      <th>Veri Türü</th>
      <th>Karşılaştırma Mantığı</th>
      <th>Dikkat Edilecek Nokta</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sayı</td>
      <td>matematiksel büyüklük</td>
      <td>tür dönüşümü hataları</td>
    </tr>
    <tr>
      <td>Metin</td>
      <td>alfabetik/sözlük sırası</td>
      <td>büyük-küçük harf farkı</td>
    </tr>
    <tr>
      <td>Tarih</td>
      <td>zaman karşılaştırması</td>
      <td>format ve saat dilimi</td>
    </tr>
    <tr>
      <td>Boolean</td>
      <td><code class="language-plaintext highlighter-rouge">true</code> / <code class="language-plaintext highlighter-rouge">false</code></td>
      <td>gereksiz <code class="language-plaintext highlighter-rouge">== true</code> kullanımı</td>
    </tr>
    <tr>
      <td>Nesne</td>
      <td>referans karşılaştırması</td>
      <td>içerik aynı olsa bile farklı olabilir</td>
    </tr>
  </tbody>
</table>

<h2 id="mini-strateji-okunabilir-koşullar-yazmak">Mini Strateji: Okunabilir Koşullar Yazmak</h2>

<p>Karmaşık kararlar yazarken karşılaştırmaları değişkenlere ayırmak kodu daha okunabilir yapar. Aşağıdaki örnek, iş kuralını neredeyse düz Türkçe gibi okutmayı hedefler:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">sepetTutari</span> <span class="o">=</span> <span class="mi">1250</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">uyeMi</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">stokVarMi</span> <span class="o">=</span> <span class="kc">true</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">indirimHakEder</span> <span class="o">=</span> <span class="nx">sepetTutari</span> <span class="o">&gt;=</span> <span class="mi">1000</span> <span class="o">&amp;&amp;</span> <span class="nx">uyeMi</span> <span class="o">===</span> <span class="kc">true</span><span class="p">;</span>
<span class="kd">const</span> <span class="nx">satinAlabilir</span> <span class="o">=</span> <span class="nx">indirimHakEder</span> <span class="o">&amp;&amp;</span> <span class="nx">stokVarMi</span> <span class="o">===</span> <span class="kc">true</span><span class="p">;</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">satinAlabilir</span><span class="p">);</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">indirimHakEder</code> ve <code class="language-plaintext highlighter-rouge">satinAlabilir</code> ara karar değişkenleridir. Böylece tek satırlık dev bir koşul yerine, mantığı parçalara bölen temiz bir yapı elde edilir.</p>

<p>Özetle karşılaştırma operatörleri, programların karar verme kaslarıdır. Doğru kullanıldıklarında kodunuz daha güvenilir, okunabilir ve tahmin edilebilir olur. Yanlış kullanıldıklarında ise “Neden bu kullanıcı içeri girdi?” gibi klasik yazılımcı dedektiflik hikâyeleri başlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="programlama" /><category term="mantıksal-operatörler" /><category term="karşılaştırma" /><summary type="html"><![CDATA[Programlamada bir uygulamanın “akıllı” görünmesini sağlayan şey çoğu zaman çok basit bir sorudur: “Bu doğru mu, değil mi?” Mantıksal karşılaştırma işlemleri; değişkenler veya sabit değerler arasında büyüklük, küçüklük, eşitlik ya da denklik gibi ilişkileri kontrol eder ve sonucu genellikle true veya false olarak üretir. Yani kod dünyasının trafik lambaları gibidirler: geç, dur, bekle!]]></summary></entry><entry><title type="html">Özyineleme ile Döngüsel Kontrol: Döngüsüz Tekrarın Zekice Yolu</title><link href="https://sonsuzus.github.io/posts/ozyineleme-ile-dongusel-kontrol-dongusuz-tekrarin-zekice-yolu/" rel="alternate" type="text/html" title="Özyineleme ile Döngüsel Kontrol: Döngüsüz Tekrarın Zekice Yolu" /><published>2026-07-19T00:00:00+00:00</published><updated>2026-07-19T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/ozyineleme-ile-dongusel-kontrol-dongusuz-tekrarin-zekice-yolu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/ozyineleme-ile-dongusel-kontrol-dongusuz-tekrarin-zekice-yolu/"><![CDATA[<p>Bir listeyi gezmek, bir dizindeki dosyaları taramak ya da ardışık adımlarla sonuca ulaşmak denince akla genellikle for ve while döngüleri gelir. Özyineleme ise aynı işi farklı bir zihinsel modelle yapar: Bir kural, problemin daha küçük bir sürümünü çözmek için kendini yeniden çağırır. Yani kontrol akışı dışarıdan dönen bir çark gibi değil, iç içe açılan matruşka bebekleri gibi ilerler.
``</p>

<h2 id="özyinelemenin-temel-fikri">Özyinelemenin Temel Fikri</h2>

<p>Özyineleme, bir fonksiyonun veya kuralın kendi kendini çağırmasıdır. Ancak bu, sonsuza kadar süren sihirli bir ayna koridoru değildir. Sağlıklı bir özyinelemeli yapı iki parçaya dayanır:</p>

<table>
  <thead>
    <tr>
      <th>Parça</th>
      <th>Görevi</th>
      <th>Basit Soru</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel durum</td>
      <td>Çağrıları durdurur</td>
      <td>Artık cevap belli mi?</td>
    </tr>
    <tr>
      <td>Özyinelemeli adım</td>
      <td>Problemi küçültür</td>
      <td>Aynı sorunun daha küçük hali nedir?</td>
    </tr>
  </tbody>
</table>

<p>Matematiksel olarak bunu şöyle düşünebiliriz: Bir listenin toplamı için $S(n)$, ilk $n$ elemanın toplamı olsun. O zaman:</p>

\[S(n) = S(n-1) + a_n\]

<p>ve temel durum:</p>

\[S(0) = 0\]

<p>Bu tanımda döngü yoktur ama tekrar vardır. Her çağrı, problemi bir adım küçültür. Liste bittiğinde sonuç geriye doğru taşınır.</p>

<h2 id="döngü-mü-özyineleme-mi">Döngü mü, Özyineleme mi?</h2>

<p>Geleneksel döngüler kontrolü açıkça yönetir: sayaç artırılır, koşul kontrol edilir, gövde çalıştırılır. Özyineleme ise kontrolü çağrı zincirine bırakır. Bu yüzden özellikle ağaçlar, klasör yapıları, grafik aramaları ve parçala-fethet algoritmalarında çok doğal görünür.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Kontrol Mantığı</th>
      <th>Güçlü Olduğu Yer</th>
      <th>Risk</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Döngü</td>
      <td>Sayaç ve koşul ile ilerler</td>
      <td>Düz listeler, basit tekrarlar</td>
      <td>Karmaşık iç içe koşullar</td>
    </tr>
    <tr>
      <td>Özyineleme</td>
      <td>Fonksiyon kendini çağırır</td>
      <td>Ağaç, alt problem, hiyerarşi</td>
      <td>Sonsuz çağrı veya stack taşması</td>
    </tr>
  </tbody>
</table>

<p>Örneğin bir listedeki sayıların toplamını özyinelemeyle hesaplayalım:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">toplam</span><span class="p">(</span><span class="nx">liste</span><span class="p">,</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">index</span> <span class="o">===</span> <span class="nx">liste</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
  <span class="k">return</span> <span class="nx">liste</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="o">+</span> <span class="nf">toplam</span><span class="p">(</span><span class="nx">liste</span><span class="p">,</span> <span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="kd">const</span> <span class="nx">sonuc</span> <span class="o">=</span> <span class="nf">toplam</span><span class="p">([</span><span class="mi">4</span><span class="p">,</span> <span class="mi">8</span><span class="p">,</span> <span class="mi">15</span><span class="p">,</span> <span class="mi">16</span><span class="p">]);</span>
<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nx">sonuc</span><span class="p">);</span> <span class="c1">// 43</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">index === liste.length</code> temel durumdur. Liste bittiğinde sıfır döner. Aksi halde mevcut eleman alınır ve listenin geri kalanı için aynı fonksiyon tekrar çağrılır. Bir döngü yazmadık ama listeyi baştan sona gezdik.</p>

<h2 id="çağrı-yığını-görünmeyen-merdiven">Çağrı Yığını: Görünmeyen Merdiven</h2>

<p>Özyineleme çalışırken her fonksiyon çağrısı bellekte çağrı yığınına eklenir. Bunu bir merdiven gibi düşünebiliriz. Önce aşağı inilir, temel duruma ulaşılır, sonra cevaplar yukarı çıkarken birleşir.</p>

<p><code class="language-plaintext highlighter-rouge">toplam([4, 8, 15], 0)</code> çağrısı kabaca şöyle açılır:</p>

<pre><code class="language-txt">4 + toplam(index 1)
4 + 8 + toplam(index 2)
4 + 8 + 15 + toplam(index 3)
4 + 8 + 15 + 0
</code></pre>

<p>Zaman karmaşıklığı her elemanı bir kez ziyaret ettiği için $O(n)$ olur. Ancak bellek tarafında da çağrı yığını kullanılır; bu nedenle ek bellek maliyeti genellikle $O(n)$ kabul edilir. Döngüsel çözümde ise çoğu zaman bellek $O(1)$ olabilir.</p>

<h2 id="kural-tabanlı-düşünmek">Kural Tabanlı Düşünmek</h2>

<p>Özyinelemeyi güçlü yapan şey, işlemi emir listesi gibi değil, kural gibi yazmamızdır. Mesela bir listede ilk çift sayıyı bulalım:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">ilkCift</span><span class="p">(</span><span class="nx">liste</span><span class="p">,</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">index</span> <span class="o">&gt;=</span> <span class="nx">liste</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">liste</span><span class="p">[</span><span class="nx">index</span><span class="p">]</span> <span class="o">%</span> <span class="mi">2</span> <span class="o">===</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="nx">liste</span><span class="p">[</span><span class="nx">index</span><span class="p">];</span>
  <span class="k">return</span> <span class="nf">ilkCift</span><span class="p">(</span><span class="nx">liste</span><span class="p">,</span> <span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>

<span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">ilkCift</span><span class="p">([</span><span class="mi">3</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">10</span><span class="p">,</span> <span class="mi">12</span><span class="p">]));</span> <span class="c1">// 10</span>
</code></pre></div></div>

<p>Burada strateji nettir: Eğer liste bittiyse yoktur. Mevcut eleman çiftse cevap odur. Değilse aynı aramayı bir sonraki elemandan başlat. Bu ifade biçimi, özellikle kuralların kendi kendini genişlettiği mantıksal programlama, ayrıştırıcılar ve yapay zeka arama problemlerinde çok okunaklıdır.</p>

<h2 id="ne-zaman-dikkatli-olmalı">Ne Zaman Dikkatli Olmalı?</h2>

<p>Özyineleme şık olabilir ama her yere serpilmiş algoritmik pul biber gibi kullanılmamalıdır. Temel durum unutulursa fonksiyon sonsuza kadar kendini çağırır. Çok büyük listelerde çağrı yığını dolabilir. Bazı diller kuyruk özyinelemesini optimize eder, bazıları etmez.</p>

<p>Kuyruk özyinelemesinde son işlem doğrudan özyinelemeli çağrıdır:</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nf">toplamKuyruk</span><span class="p">(</span><span class="nx">liste</span><span class="p">,</span> <span class="nx">index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">,</span> <span class="nx">acc</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
  <span class="k">if </span><span class="p">(</span><span class="nx">index</span> <span class="o">===</span> <span class="nx">liste</span><span class="p">.</span><span class="nx">length</span><span class="p">)</span> <span class="k">return</span> <span class="nx">acc</span><span class="p">;</span>
  <span class="k">return</span> <span class="nf">toplamKuyruk</span><span class="p">(</span><span class="nx">liste</span><span class="p">,</span> <span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">,</span> <span class="nx">acc</span> <span class="o">+</span> <span class="nx">liste</span><span class="p">[</span><span class="nx">index</span><span class="p">]);</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">acc</code>, yani biriktirici, ara sonucu taşır. Teorik olarak bu yapı daha kolay optimize edilebilir.</p>

<p>Sonuç olarak özyineleme, döngülerin rakibi değil; tekrar eden işlemleri farklı bir soyutlama katmanında ifade etmenin yoludur. Problem doğal olarak alt problemlere ayrılıyorsa, özyineleme kodu hem daha kısa hem daha açıklayıcı hale getirebilir. Yeter ki şu üç soruyu unutmayalım: Nerede duruyorum, problemi nasıl küçültüyorum ve çağrılar bellekte ne kadar yer kaplıyor?</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="özyineleme" /><category term="recursion" /><category term="algoritma" /><summary type="html"><![CDATA[Bir listeyi gezmek, bir dizindeki dosyaları taramak ya da ardışık adımlarla sonuca ulaşmak denince akla genellikle for ve while döngüleri gelir. Özyineleme ise aynı işi farklı bir zihinsel modelle yapar: Bir kural, problemin daha küçük bir sürümünü çözmek için kendini yeniden çağırır. Yani kontrol akışı dışarıdan dönen bir çark gibi değil, iç içe açılan matruşka bebekleri gibi ilerler.]]></summary></entry><entry><title type="html">Prolog’da Aritmetik: is Operatörüyle Sembolleri Sonuca Dönüştürmek</title><link href="https://sonsuzus.github.io/posts/prologda-aritmetik-is-operatoruyle-sembolleri-sonuca-donusturmek/" rel="alternate" type="text/html" title="Prolog’da Aritmetik: is Operatörüyle Sembolleri Sonuca Dönüştürmek" /><published>2026-07-19T00:00:00+00:00</published><updated>2026-07-19T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/prologda-aritmetik-is-operatoruyle-sembolleri-sonuca-donusturmek</id><content type="html" xml:base="https://sonsuzus.github.io/posts/prologda-aritmetik-is-operatoruyle-sembolleri-sonuca-donusturmek/"><![CDATA[<p>Programlamada aritmetik deyince çoğu dilde <code class="language-plaintext highlighter-rouge">x = 2 + 3</code> yazıp sonucu bekleriz. Prolog ise biraz daha felsefi davranır: Önce sembolleri, terimleri ve ilişkileri düşünür; hesaplama ise özel olarak istendiğinde yapılır. İşte <code class="language-plaintext highlighter-rouge">is</code> operatörü tam bu noktada sahneye çıkar: Matematiksel formülü sadece sembolik bir yapı olarak tutmak yerine, gerçekten hesaplar ve kesin sonucu yeni bir değişkene bağlar.
``
Prolog’da <code class="language-plaintext highlighter-rouge">2 + 3</code> ifadesi ilk bakışta basit görünür. Fakat Prolog için bu ifade, otomatik olarak 5’e dönüşen bir işlem değil; <code class="language-plaintext highlighter-rouge">+(2, 3)</code> şeklinde okunabilecek bir terimdir. Yani sembolik bir ağaç gibi düşünebiliriz. Eğer hesaplama yapılmasını istiyorsak <code class="language-plaintext highlighter-rouge">is</code> kullanırız:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nv">X</span> <span class="ss">is</span> <span class="m">2</span> <span class="o">+</span> <span class="m">3</span><span class="p">.</span>
<span class="c1">% X = 5</span>
</code></pre></div></div>

<p>Burada sağ taraf, yani <code class="language-plaintext highlighter-rouge">2 + 3</code>, önce değerlendirilir. Sonra elde edilen sonuç sol taraftaki değişkene bağlanır. Matematiksel olarak söylemek gerekirse:</p>

<p>$X = 2 + 3 \Rightarrow X = 5$</p>

<p>Ama Prolog’daki <code class="language-plaintext highlighter-rouge">=</code> operatörü ile bu aynı şey değildir. <code class="language-plaintext highlighter-rouge">=</code> birleştirme, yani unification yapar. Hesaplama yapmaz. Bu ayrım Prolog öğrenirken küçük ama çok kritik bir virajdır.</p>

<table>
  <thead>
    <tr>
      <th>İfade</th>
      <th>Prolog’un Davranışı</th>
      <th>Sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">X = 2 + 3</code></td>
      <td>Sembolik terimi bağlar</td>
      <td><code class="language-plaintext highlighter-rouge">X = 2+3</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">X is 2 + 3</code></td>
      <td>Sağ tarafı hesaplar</td>
      <td><code class="language-plaintext highlighter-rouge">X = 5</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">5 is 2 + 3</code></td>
      <td>Sağ tarafı hesaplayıp karşılaştırır gibi birleştirir</td>
      <td>doğru</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">2 + 3 is 5</code></td>
      <td>Sol taraf hesaplanabilir değişken/ sayı gibi uygun değildir</td>
      <td>genellikle hata</td>
    </tr>
  </tbody>
</table>

<p>Bunu bir mutfak benzetmesiyle düşünelim. <code class="language-plaintext highlighter-rouge">2 + 3</code> bir yemek tarifi olsun. <code class="language-plaintext highlighter-rouge">=</code> operatörü tarifi deftere yapıştırır. <code class="language-plaintext highlighter-rouge">is</code> ise mutfağa girer, malzemeleri toplar ve tabağa gerçek yemeği koyar. Tarif başka, yemek başka!</p>

<p>Aşağıdaki örnek, sembolik bağlama ile gerçek hesaplama arasındaki farkı gösterir:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">sembolik_ornek</span><span class="p">(</span><span class="nv">X</span><span class="p">)</span> <span class="p">:-</span>
    <span class="nv">X</span> <span class="o">=</span> <span class="m">10</span> <span class="o">*</span> <span class="m">4</span> <span class="o">+</span> <span class="m">2</span><span class="p">.</span>

<span class="ss">hesapli_ornek</span><span class="p">(</span><span class="nv">X</span><span class="p">)</span> <span class="p">:-</span>
    <span class="nv">X</span> <span class="ss">is</span> <span class="m">10</span> <span class="o">*</span> <span class="m">4</span> <span class="o">+</span> <span class="m">2</span><span class="p">.</span>
</code></pre></div></div>

<p>İlk kural çağrıldığında <code class="language-plaintext highlighter-rouge">X</code>, <code class="language-plaintext highlighter-rouge">10*4+2</code> terimine bağlanır. İkinci kuralda ise işlem önceliği uygulanır ve sonuç <code class="language-plaintext highlighter-rouge">42</code> olur. Yani:</p>

<p>$10 \times 4 + 2 = 42$</p>

<p><code class="language-plaintext highlighter-rouge">is</code> operatörünün önemli bir şartı vardır: Sağ taraftaki ifade hesaplanabilir olmalıdır. Yani içinde değeri bilinmeyen bir değişken varsa Prolog hesaplama yapamaz.</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">?-</span> <span class="nv">X</span> <span class="ss">is</span> <span class="nv">Y</span> <span class="o">+</span> <span class="m">1</span><span class="p">.</span>
<span class="c1">% Hata: Y henüz bir sayıya bağlı değil</span>
</code></pre></div></div>

<p>Doğru kullanımda önce <code class="language-plaintext highlighter-rouge">Y</code> bağlanmalıdır:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">?-</span> <span class="nv">Y</span> <span class="o">=</span> <span class="m">4</span><span class="p">,</span> <span class="nv">X</span> <span class="ss">is</span> <span class="nv">Y</span> <span class="o">+</span> <span class="m">1</span><span class="p">.</span>
<span class="c1">% Y = 4,</span>
<span class="c1">% X = 5</span>
</code></pre></div></div>

<p>Bu davranış, Prolog’un soldan sağa hedef çözme mantığıyla ilgilidir. Prolog önce <code class="language-plaintext highlighter-rouge">Y = 4</code> hedefini çözer, sonra <code class="language-plaintext highlighter-rouge">X is Y + 1</code> ifadesinde artık <code class="language-plaintext highlighter-rouge">Y</code> değerini bildiği için hesaplama yapabilir.</p>

<p>Karşılaştırma işlemlerinde de dikkatli olmak gerekir. <code class="language-plaintext highlighter-rouge">is</code>, sonuç üretmek içindir; iki aritmetik ifadenin değerini karşılaştırmak için <code class="language-plaintext highlighter-rouge">=:=</code> kullanılır.</p>

<table>
  <thead>
    <tr>
      <th>Amaç</th>
      <th>Kullanım</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Sonuç hesapla ve bağla</td>
      <td><code class="language-plaintext highlighter-rouge">is</code></td>
      <td><code class="language-plaintext highlighter-rouge">X is 7 * 6</code></td>
    </tr>
    <tr>
      <td>Sembolik birleştirme yap</td>
      <td><code class="language-plaintext highlighter-rouge">=</code></td>
      <td><code class="language-plaintext highlighter-rouge">X = 7 * 6</code></td>
    </tr>
    <tr>
      <td>Aritmetik eşitlik kontrol et</td>
      <td><code class="language-plaintext highlighter-rouge">=:=</code></td>
      <td><code class="language-plaintext highlighter-rouge">2 + 3 =:= 5</code></td>
    </tr>
    <tr>
      <td>Aritmetik eşitsizlik kontrol et</td>
      <td><code class="language-plaintext highlighter-rouge">=\=</code></td>
      <td><code class="language-plaintext highlighter-rouge">2 + 3 =\= 6</code></td>
    </tr>
  </tbody>
</table>

<p>Küçük bir alan hesabı örneği yazalım:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">alan_dikdortgen</span><span class="p">(</span><span class="nv">Genislik</span><span class="p">,</span> <span class="nv">Yukseklik</span><span class="p">,</span> <span class="nv">Alan</span><span class="p">)</span> <span class="p">:-</span>
    <span class="nv">Alan</span> <span class="ss">is</span> <span class="nv">Genislik</span> <span class="o">*</span> <span class="nv">Yukseklik</span><span class="p">.</span>

<span class="ss">cevre_dikdortgen</span><span class="p">(</span><span class="nv">Genislik</span><span class="p">,</span> <span class="nv">Yukseklik</span><span class="p">,</span> <span class="nv">Cevre</span><span class="p">)</span> <span class="p">:-</span>
    <span class="nv">Cevre</span> <span class="ss">is</span> <span class="m">2</span> <span class="o">*</span> <span class="p">(</span><span class="nv">Genislik</span> <span class="o">+</span> <span class="nv">Yukseklik</span><span class="p">).</span>
</code></pre></div></div>

<p>Bu kurallar şu şekilde çalışır:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">?-</span> <span class="ss">alan_dikdortgen</span><span class="p">(</span><span class="m">5</span><span class="p">,</span> <span class="m">8</span><span class="p">,</span> <span class="nv">A</span><span class="p">).</span>
<span class="c1">% A = 40</span>

<span class="o">?-</span> <span class="ss">cevre_dikdortgen</span><span class="p">(</span><span class="m">5</span><span class="p">,</span> <span class="m">8</span><span class="p">,</span> <span class="nv">C</span><span class="p">).</span>
<span class="c1">% C = 26</span>
</code></pre></div></div>

<p>Teorik olarak burada yaptığımız şey, bir bağıntının içinde deterministik bir hesaplama adımı tanımlamaktır. <code class="language-plaintext highlighter-rouge">alan_dikdortgen(5, 8, A)</code> ilişkisi, $A = 5 \times 8$ formülünü kullanır ve <code class="language-plaintext highlighter-rouge">A</code> değişkenini kesin sonuç olan 40’a bağlar.</p>

<p>Özetle: Prolog’da matematiksel formül yazmak, onun otomatik hesaplanacağı anlamına gelmez. <code class="language-plaintext highlighter-rouge">=</code> sembolik dünyada kalır; <code class="language-plaintext highlighter-rouge">is</code> ise hesaplama motorunu çalıştırır. Eğer formülün gerçekten değerlendirilmesini ve sonucun yeni bir değişkene atanmasını istiyorsanız, doğru araç <code class="language-plaintext highlighter-rouge">is</code> operatörüdür. Prolog’un büyüsü de burada başlar: Sembollerle düşünür, gerektiğinde sayılarla hesaplar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="prolog" /><category term="aritmetik" /><category term="mantıksal-programlama" /><summary type="html"><![CDATA[Programlamada aritmetik deyince çoğu dilde x = 2 + 3 yazıp sonucu bekleriz. Prolog ise biraz daha felsefi davranır: Önce sembolleri, terimleri ve ilişkileri düşünür; hesaplama ise özel olarak istendiğinde yapılır. İşte is operatörü tam bu noktada sahneye çıkar: Matematiksel formülü sadece sembolik bir yapı olarak tutmak yerine, gerçekten hesaplar ve kesin sonucu yeni bir değişkene bağlar.]]></summary></entry><entry><title type="html">Yazdırma ve Çıktı İşlemleri: Standart Yüklemlerle Ekrana Konuşan Programlar</title><link href="https://sonsuzus.github.io/posts/yazdirma-ve-cikti-islemleri-standart-yuklemlerle-ekrana-konusan-programlar/" rel="alternate" type="text/html" title="Yazdırma ve Çıktı İşlemleri: Standart Yüklemlerle Ekrana Konuşan Programlar" /><published>2026-07-19T00:00:00+00:00</published><updated>2026-07-19T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/yazdirma-ve-cikti-islemleri-standart-yuklemlerle-ekrana-konusan-programlar</id><content type="html" xml:base="https://sonsuzus.github.io/posts/yazdirma-ve-cikti-islemleri-standart-yuklemlerle-ekrana-konusan-programlar/"><![CDATA[<p>Bir programın kullanıcıyla ilk selamlaşması çoğu zaman ekrana yazdırdığı küçücük bir metinle başlar. Mantıksal programlama dünyasında, özellikle Prolog gibi dillerde, bu iş “fonksiyon çağırmak”tan çok “yüklem çalıştırmak” şeklinde düşünülür. Yani ekrana metin basmak, değişkenin değerini görmek veya satır atlamak için sisteme gömülü standart yüklemlerden yararlanırız.
``</p>

<p>Prolog’da çıktı işlemlerini anlamak için önce şu fikri netleştirelim: Prolog programı, doğruluğu araştırılan ilişkilerden oluşur. Ancak bazen yalnızca “sonuç doğru mu?” sorusunu değil, “bu sonucu kullanıcıya nasıl gösteririm?” sorusunu da cevaplamak isteriz. İşte <code class="language-plaintext highlighter-rouge">write/1</code>, <code class="language-plaintext highlighter-rouge">writeln/1</code>, <code class="language-plaintext highlighter-rouge">nl/0</code> ve <code class="language-plaintext highlighter-rouge">format/2</code> gibi yüklemler bu noktada sahneye çıkar.</p>

<p>Teorik olarak çıktı, bir terimin standart çıktı akışına gönderilmesidir. Bunu küçük bir modelle düşünebiliriz:</p>

<p>$Program \rightarrow Standart\ Çıktı \rightarrow Ekran$</p>

<p>Eğer elimizde <code class="language-plaintext highlighter-rouge">X = 42</code> gibi bir değişken bağlaması varsa, <code class="language-plaintext highlighter-rouge">write(X)</code> çağrısı artık ekrana <code class="language-plaintext highlighter-rouge">42</code> değerini taşır. Prolog’da değişkenler başlangıçta bilinmeyen varlıklardır; değerleri birleştirme, yani unification süreciyle belirlenir. Kısaca:</p>

<p>$X = Değer \Rightarrow write(X) = Değerin\ gösterimi$</p>

<p>Aşağıdaki tablo temel çıktı yüklemlerini karşılaştırır:</p>

<table>
  <thead>
    <tr>
      <th>Yüklem</th>
      <th>Görevi</th>
      <th style="text-align: right">Yeni satır ekler mi?</th>
      <th>Tipik kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">write/1</code></td>
      <td>Terimi ekrana yazar</td>
      <td style="text-align: right">Hayır</td>
      <td>Değişken veya metin göstermek</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">writeln/1</code></td>
      <td>Terimi yazar ve satır atlar</td>
      <td style="text-align: right">Evet</td>
      <td>Okunabilir listeleme</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">nl/0</code></td>
      <td>Sadece yeni satıra geçer</td>
      <td style="text-align: right">Evet</td>
      <td>Satır düzeni kurmak</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">format/2</code></td>
      <td>Şablonlu çıktı üretir</td>
      <td style="text-align: right">İsteğe bağlı</td>
      <td>Raporlama, hizalama</td>
    </tr>
  </tbody>
</table>

<p>En basit örnekle başlayalım:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">selamla</span> <span class="p">:-</span>
    <span class="ss">write</span><span class="p">(</span><span class="ss">'Merhaba Prolog!'</span><span class="p">),</span>
    <span class="ss">nl</span><span class="p">,</span>
    <span class="ss">write</span><span class="p">(</span><span class="ss">'Bugun cikti islemlerini ogreniyoruz.'</span><span class="p">).</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">selamla/0</code> adlı bir yüklem tanımlıyoruz. İlk <code class="language-plaintext highlighter-rouge">write/1</code> metni ekrana basar, <code class="language-plaintext highlighter-rouge">nl/0</code> imleci bir alt satıra indirir, ikinci <code class="language-plaintext highlighter-rouge">write/1</code> ise yeni satırdan devam eder. Burada önemli nokta şudur: <code class="language-plaintext highlighter-rouge">write/1</code> yazdırır ama satır sonunu kendiliğinden eklemez. Bu yüzden <code class="language-plaintext highlighter-rouge">nl</code> küçük ama kahraman bir yardımcıdır.</p>

<p>Değişken değerlerini göstermek için de aynı mantık geçerlidir:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">not_goster</span><span class="p">(</span><span class="nv">Isim</span><span class="p">,</span> <span class="nv">Not</span><span class="p">)</span> <span class="p">:-</span>
    <span class="ss">write</span><span class="p">(</span><span class="nv">Isim</span><span class="p">),</span>
    <span class="ss">write</span><span class="p">(</span><span class="ss">' isimli ogrencinin notu: '</span><span class="p">),</span>
    <span class="ss">write</span><span class="p">(</span><span class="nv">Not</span><span class="p">),</span>
    <span class="ss">nl</span><span class="p">.</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">not_goster('Ayse', 95).</code> sorgusu çalıştırıldığında ekranda okunabilir bir cümle oluşur. Burada Prolog, <code class="language-plaintext highlighter-rouge">Isim</code> ve <code class="language-plaintext highlighter-rouge">Not</code> değişkenlerini çağrı sırasında aldığı değerlere bağlar. Böylece çıktı yalnızca sabit metinden değil, çalışma zamanında gelen bilgilerden oluşur.</p>

<p>Daha düzenli ve profesyonel çıktılar için <code class="language-plaintext highlighter-rouge">format/2</code> oldukça kullanışlıdır. <code class="language-plaintext highlighter-rouge">format/2</code>, bir şablon ve bu şablona yerleştirilecek değerler listesiyle çalışır:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">rapor</span><span class="p">(</span><span class="nv">Isim</span><span class="p">,</span> <span class="nv">Puan</span><span class="p">)</span> <span class="p">:-</span>
    <span class="ss">format</span><span class="p">(</span><span class="ss">'Ogrenci: ~w~nPuan: ~w~n'</span><span class="p">,</span> <span class="p">[</span><span class="nv">Isim</span><span class="p">,</span> <span class="nv">Puan</span><span class="p">]).</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">~w</code>, verilen değeri yazdırır; <code class="language-plaintext highlighter-rouge">~n</code> ise yeni satır anlamına gelir. Yani <code class="language-plaintext highlighter-rouge">format/2</code>, <code class="language-plaintext highlighter-rouge">write</code> ve <code class="language-plaintext highlighter-rouge">nl</code> ikilisini daha kontrollü bir biçimde kullanmamızı sağlar. Özellikle birden fazla değeri aynı çıktıda göstermek istediğimizde kod daha okunur hale gelir.</p>

<table>
  <thead>
    <tr>
      <th>Amaç</th>
      <th>Daha basit yaklaşım</th>
      <th>Daha düzenli yaklaşım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Tek metin yazmak</td>
      <td><code class="language-plaintext highlighter-rouge">write('Selam')</code></td>
      <td><code class="language-plaintext highlighter-rouge">writeln('Selam')</code></td>
    </tr>
    <tr>
      <td>Satır atlamak</td>
      <td><code class="language-plaintext highlighter-rouge">nl</code></td>
      <td><code class="language-plaintext highlighter-rouge">format('~n', [])</code></td>
    </tr>
    <tr>
      <td>Değişkenli cümle</td>
      <td>Çoklu <code class="language-plaintext highlighter-rouge">write/1</code></td>
      <td><code class="language-plaintext highlighter-rouge">format/2</code></td>
    </tr>
    <tr>
      <td>Rapor üretmek</td>
      <td>Uzun ve parçalı kod</td>
      <td>Şablonlu çıktı</td>
    </tr>
  </tbody>
</table>

<p>Bir mini örnekle konuyu bağlayalım:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">urun_etiketi</span><span class="p">(</span><span class="nv">Ad</span><span class="p">,</span> <span class="nv">Fiyat</span><span class="p">,</span> <span class="nv">Stok</span><span class="p">)</span> <span class="p">:-</span>
    <span class="nv">ToplamDeger</span> <span class="ss">is</span> <span class="nv">Fiyat</span> <span class="o">*</span> <span class="nv">Stok</span><span class="p">,</span>
    <span class="ss">format</span><span class="p">(</span><span class="ss">'Urun: ~w~n'</span><span class="p">,</span> <span class="p">[</span><span class="nv">Ad</span><span class="p">]),</span>
    <span class="ss">format</span><span class="p">(</span><span class="ss">'Birim fiyat: ~w TL~n'</span><span class="p">,</span> <span class="p">[</span><span class="nv">Fiyat</span><span class="p">]),</span>
    <span class="ss">format</span><span class="p">(</span><span class="ss">'Stok: ~w adet~n'</span><span class="p">,</span> <span class="p">[</span><span class="nv">Stok</span><span class="p">]),</span>
    <span class="ss">format</span><span class="p">(</span><span class="ss">'Toplam stok degeri: ~w TL~n'</span><span class="p">,</span> <span class="p">[</span><span class="nv">ToplamDeger</span><span class="p">]).</span>
</code></pre></div></div>

<p>Bu yüklem, ürün bilgilerini hesaplayıp okunabilir biçimde gösterir. <code class="language-plaintext highlighter-rouge">is/2</code> aritmetik hesaplama yapar; ardından <code class="language-plaintext highlighter-rouge">format/2</code> sonucu ekrana taşır. Matematiksel olarak hesaplanan değer şudur:</p>

<p>$ToplamDeger = Fiyat \times Stok$</p>

<p>Sonuç olarak çıktı işlemleri, programın dış dünyaya açılan penceresidir. <code class="language-plaintext highlighter-rouge">write/1</code> hızlı ve basittir, <code class="language-plaintext highlighter-rouge">nl/0</code> satır düzenini sağlar, <code class="language-plaintext highlighter-rouge">writeln/1</code> pratiklik sunar, <code class="language-plaintext highlighter-rouge">format/2</code> ise ciddi raporların yıldızıdır. Kodunuz doğru çalışabilir; ama iyi biçimlendirilmiş çıktı, kullanıcının “Evet, bu program ne yaptığını biliyor!” demesini sağlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Prolog" /><category term="çıktı işlemleri" /><category term="standart yüklemler" /><summary type="html"><![CDATA[Bir programın kullanıcıyla ilk selamlaşması çoğu zaman ekrana yazdırdığı küçücük bir metinle başlar. Mantıksal programlama dünyasında, özellikle Prolog gibi dillerde, bu iş “fonksiyon çağırmak”tan çok “yüklem çalıştırmak” şeklinde düşünülür. Yani ekrana metin basmak, değişkenin değerini görmek veya satır atlamak için sisteme gömülü standart yüklemlerden yararlanırız.]]></summary></entry><entry><title type="html">Değişkenler ve Atama Mantığı: Büyük Harfli Sembollerin Gizli Dedektifliği</title><link href="https://sonsuzus.github.io/posts/degiskenler-ve-atama-mantigi-buyuk-harfli-sembollerin-gizli-dedektifligi/" rel="alternate" type="text/html" title="Değişkenler ve Atama Mantığı: Büyük Harfli Sembollerin Gizli Dedektifliği" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/degiskenler-ve-atama-mantigi-buyuk-harfli-sembollerin-gizli-dedektifligi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/degiskenler-ve-atama-mantigi-buyuk-harfli-sembollerin-gizli-dedektifligi/"><![CDATA[<p>Bir programlama dilinde değişken deyince aklımıza çoğu zaman kutular, etiketler ve bellekte duran değerler gelir. Mantıksal programlamada, özellikle Prolog tarzı dillerde ise değişken biraz daha dedektif gibidir: Büyük harfle başlayan bir sembol, sorgu anında henüz bilinmeyen bir değeri temsil eder ve sistem arka planda onu uygun gerçeklerle eşleştirmeye çalışır.
``
Bu yaklaşımın kalbinde atama değil, daha doğru adıyla eşleştirme yani unification vardır. Klasik dillerde x = 5 dediğimizde x isimli yere 5 değerini koyarız. Mantıksal programlamada ise X = 5 ifadesi, X bilinmiyorsa onu 5 ile uyumlu hale getirir. Eğer X zaten başka bir değerle eşleşmişse, sistem bu eşleşmenin çelişip çelişmediğine bakar.</p>

<p>Basitçe düşünelim: elimizde bazı bilgiler olsun.</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">seviyor</span><span class="p">(</span><span class="ss">ali</span><span class="p">,</span> <span class="ss">kahve</span><span class="p">).</span>
<span class="ss">seviyor</span><span class="p">(</span><span class="ss">ayse</span><span class="p">,</span> <span class="ss">cay</span><span class="p">).</span>
<span class="ss">seviyor</span><span class="p">(</span><span class="ss">ali</span><span class="p">,</span> <span class="ss">kitap</span><span class="p">).</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">ali</code>, <code class="language-plaintext highlighter-rouge">kahve</code>, <code class="language-plaintext highlighter-rouge">ayse</code> gibi küçük harfle başlayan ifadeler sabit değerlerdir. Yani sistem için bunlar zaten bilinen şeylerdir. Ama <code class="language-plaintext highlighter-rouge">X</code> ya da <code class="language-plaintext highlighter-rouge">Ne</code> gibi büyük harfle başlayan semboller değişkendir. Şu sorguyu yazdığımızda:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">seviyor</span><span class="p">(</span><span class="ss">ali</span><span class="p">,</span> <span class="nv">X</span><span class="p">).</span>
</code></pre></div></div>

<p>sistem şunu sorar: Ali neyi seviyor? Arka planda tüm <code class="language-plaintext highlighter-rouge">seviyor</code> kayıtlarını dolaşır ve birinci konumu <code class="language-plaintext highlighter-rouge">ali</code> olanları bulur. Sonuçlar sırayla şöyle eşleşir:</p>

<table>
  <thead>
    <tr>
      <th>Sorgu</th>
      <th>Eşleşen gerçek</th>
      <th>Değişkenin değeri</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">seviyor(ali, X)</code></td>
      <td><code class="language-plaintext highlighter-rouge">seviyor(ali, kahve)</code></td>
      <td><code class="language-plaintext highlighter-rouge">X = kahve</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">seviyor(ali, X)</code></td>
      <td><code class="language-plaintext highlighter-rouge">seviyor(ali, kitap)</code></td>
      <td><code class="language-plaintext highlighter-rouge">X = kitap</code></td>
    </tr>
  </tbody>
</table>

<p>Yani değişken, tek bir sihirli cevap değil, mümkün olan cevaplar kümesidir. Matematiksel olarak bunu şöyle düşünebiliriz: Bir ilişki $R(kisi, nesne)$ olsun. <code class="language-plaintext highlighter-rouge">seviyor(ali, X)</code> sorgusu aslında $R(ali, X)$ koşulunu sağlayan tüm $X$ değerlerini arar. Sonuç kümesi ${kahve, kitap}$ olur.</p>

<p>Bu mantık, klasik atamadan önemli ölçüde farklıdır:</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Klasik Değişken</th>
      <th>Mantıksal Değişken</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Başlangıç durumu</td>
      <td>Genelde değer atanır</td>
      <td>Bilinmeyen olabilir</td>
    </tr>
    <tr>
      <td>İşlem tipi</td>
      <td>Atama</td>
      <td>Eşleştirme</td>
    </tr>
    <tr>
      <td>Yön</td>
      <td>Soldan sağa düşünülür</td>
      <td>İlişki yönsüz çalışabilir</td>
    </tr>
    <tr>
      <td>Örnek</td>
      <td><code class="language-plaintext highlighter-rouge">x = 5</code></td>
      <td><code class="language-plaintext highlighter-rouge">X = 5</code></td>
    </tr>
    <tr>
      <td>Amaç</td>
      <td>Değeri saklamak</td>
      <td>Uygun değeri bulmak</td>
    </tr>
  </tbody>
</table>

<p>Daha eğlenceli bir örnek yapalım. Diyelim ki aile ilişkilerimiz var:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">ebeveyn</span><span class="p">(</span><span class="ss">aylin</span><span class="p">,</span> <span class="ss">zeynep</span><span class="p">).</span>
<span class="ss">ebeveyn</span><span class="p">(</span><span class="ss">murat</span><span class="p">,</span> <span class="ss">zeynep</span><span class="p">).</span>
<span class="ss">ebeveyn</span><span class="p">(</span><span class="ss">zeynep</span><span class="p">,</span> <span class="ss">deniz</span><span class="p">).</span>

<span class="ss">anne_baba</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="nv">Y</span><span class="p">)</span> <span class="p">:-</span> <span class="ss">ebeveyn</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="nv">Y</span><span class="p">).</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">anne_baba(X, Y)</code> kuralı, X kişisinin Y kişisinin ebeveyni olduğunu söyler. Şu sorgu:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">anne_baba</span><span class="p">(</span><span class="nv">Kim</span><span class="p">,</span> <span class="ss">zeynep</span><span class="p">).</span>
</code></pre></div></div>

<p>sisteme şunu dedirtir: Zeynep’in ebeveyni kim? Cevaplar <code class="language-plaintext highlighter-rouge">Kim = aylin</code> ve <code class="language-plaintext highlighter-rouge">Kim = murat</code> olur. Değişkenin adı <code class="language-plaintext highlighter-rouge">Kim</code> seçildiği için insan gözüyle de okunaklıdır; fakat sistem için önemli olan büyük harfle başlamasıdır.</p>

<p>Eşleştirme süreci kabaca şöyle işler:</p>

<ol>
  <li>Sorgudaki yapı ile veritabanındaki yapı karşılaştırılır.</li>
  <li>Sabitler aynı mı diye bakılır.</li>
  <li>Değişken varsa uygun değerle bağlanır.</li>
  <li>Çelişki yoksa çözüm üretilir.</li>
  <li>Başka olasılık varsa geri izleme ile yeni çözüm aranır.</li>
</ol>

<p>Örneğin:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">seviyor</span><span class="p">(</span><span class="nv">Kisi</span><span class="p">,</span> <span class="ss">kahve</span><span class="p">).</span>
</code></pre></div></div>

<p>Bu sorguda <code class="language-plaintext highlighter-rouge">Kisi</code> bilinmeyendir. Sistem kahveyi sevenleri arar. Eğer <code class="language-plaintext highlighter-rouge">seviyor(ali, kahve)</code> varsa <code class="language-plaintext highlighter-rouge">Kisi = ali</code> sonucu çıkar. Burada değişken yalnızca boşluk doldurmaz; sorgunun yönünü de esnetir. Aynı ilişkiyle hem Ali’nin ne sevdiğini hem de kahveyi kimin sevdiğini sorabiliriz.</p>

<p>Bu fikri denklem çözmeye benzetebiliriz. $X + 2 = 5$ denkleminde $X$ bilinmeyendir ve $X = 3$ bulunur. Mantıksal programlamada da <code class="language-plaintext highlighter-rouge">seviyor(ali, X)</code> ifadesi, ilişki tablosunda X’i tamamlayacak değerleri arar. Ancak burada tek bir sayı yerine sembolik bilgiler ve birden fazla olası cevap olabilir.</p>

<p>Sonuç olarak büyük harfle başlayan değişkenler, mantıksal programlamanın en güçlü parçalarındandır. Onlar bellekteki sıradan kutular değil, soru işaretleridir. Programcı olarak siz ilişkiyi tanımlarsınız; motor ise bilinmeyenleri uygun değerlerle eşleştirir. Küçük harfli sabitler sahnedeki oyuncularsa, büyük harfli değişkenler dedektif şapkası takıp sahne arkasında kimin kimle eşleştiğini bulan zeki yardımcılarımızdır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="değişkenler" /><category term="mantıksal-programlama" /><category term="prolog" /><summary type="html"><![CDATA[Bir programlama dilinde değişken deyince aklımıza çoğu zaman kutular, etiketler ve bellekte duran değerler gelir. Mantıksal programlamada, özellikle Prolog tarzı dillerde ise değişken biraz daha dedektif gibidir: Büyük harfle başlayan bir sembol, sorgu anında henüz bilinmeyen bir değeri temsil eder ve sistem arka planda onu uygun gerçeklerle eşleştirmeye çalışır.]]></summary></entry><entry><title type="html">Gerçekler ve Bilgi Tabanı: Dünyayı Kurallarla Anlatmak</title><link href="https://sonsuzus.github.io/posts/gercekler-ve-bilgi-tabani-dunyayi-kurallarla-anlatmak/" rel="alternate" type="text/html" title="Gerçekler ve Bilgi Tabanı: Dünyayı Kurallarla Anlatmak" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/gercekler-ve-bilgi-tabani-dunyayi-kurallarla-anlatmak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/gercekler-ve-bilgi-tabani-dunyayi-kurallarla-anlatmak/"><![CDATA[<p>Bir yazılıma dünyayı öğretmek isteseydik nereden başlardık? Kedilerin memeli olduğu, Ankara’nın Türkiye’nin başkenti olduğu, suyun 0°C’de donduğu gibi kesin kabul ettiğimiz küçük bilgi parçacıklarıyla. İşte bu küçük, değişmez ve doğrulanabilir ifadelere yapay zekâ ve mantıksal sistemlerde “gerçek” denir. Gerçekler bir araya geldiğinde ise yazılımın akıl yürütebileceği bir bilgi tabanı oluşur.
``
Bilgi tabanı, klasik veritabanından biraz farklı düşünülmelidir. Bir veritabanı genellikle “ne saklıyorum?” sorusuna odaklanır; bilgi tabanı ise “bu saklananlardan ne çıkarabilirim?” sorusunu da önemser. Örneğin <code class="language-plaintext highlighter-rouge">insan(Ayşe)</code> ve <code class="language-plaintext highlighter-rouge">insanlar ölümlüdür</code> bilgilerini biliyorsak, sistem <code class="language-plaintext highlighter-rouge">Ayşe ölümlüdür</code> sonucuna ulaşabilir. Bu, ham veri depolamaktan daha fazlasıdır: kurallar üzerinden anlam üretmektir.</p>

<p>Teorik olarak bir gerçek, çoğu zaman özne-yüklem-nesne üçlüsüyle ifade edilir. Mesela “Pamuk bir kedidir” cümlesi şu şekilde modellenebilir:</p>

<p>$kedi(Pamuk)$</p>

<p>“Nesne A, nesne B ile ilişkilidir” demek için de iki değişkenli yüklemler kullanılır:</p>

<p>$sahibi(Pamuk, Zeynep)$</p>

<p>Burada <code class="language-plaintext highlighter-rouge">sahibi</code> ilişkiyi, <code class="language-plaintext highlighter-rouge">Pamuk</code> ve <code class="language-plaintext highlighter-rouge">Zeynep</code> ise ilişkiye katılan nesneleri temsil eder. Bilgi tabanının gücü, bu küçük ifadelerin net ve tutarlı olmasından gelir. Çünkü mantıksal çıkarımda belirsizlik sevmez; yanlış ya da çelişkili gerçekler, sistemin tuhaf sonuçlar üretmesine neden olabilir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Açıklama</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Nesne</td>
      <td>Dünyadaki varlık</td>
      <td><code class="language-plaintext highlighter-rouge">Pamuk</code>, <code class="language-plaintext highlighter-rouge">Ankara</code></td>
    </tr>
    <tr>
      <td>Özellik</td>
      <td>Nesnenin niteliği</td>
      <td><code class="language-plaintext highlighter-rouge">beyaz(Pamuk)</code></td>
    </tr>
    <tr>
      <td>İlişki</td>
      <td>İki veya daha çok nesne arasındaki bağ</td>
      <td><code class="language-plaintext highlighter-rouge">başkentidir(Ankara, Türkiye)</code></td>
    </tr>
    <tr>
      <td>Kural</td>
      <td>Gerçeklerden yeni sonuç çıkarma şablonu</td>
      <td><code class="language-plaintext highlighter-rouge">kedi(X) -&gt; memeli(X)</code></td>
    </tr>
  </tbody>
</table>

<p>Basit bir bilgi tabanını kodla hayal edelim. Aşağıdaki Python örneği, gerçekleri üçlü yapılar halinde tutar ve belirli bir ilişkiyi sorgular:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">facts</span> <span class="o">=</span> <span class="p">{</span>
    <span class="p">(</span><span class="sh">'</span><span class="s">Pamuk</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">tür</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">kedi</span><span class="sh">'</span><span class="p">),</span>
    <span class="p">(</span><span class="sh">'</span><span class="s">Köpük</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">tür</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">köpek</span><span class="sh">'</span><span class="p">),</span>
    <span class="p">(</span><span class="sh">'</span><span class="s">Ankara</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">başkentidir</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">Türkiye</span><span class="sh">'</span><span class="p">),</span>
    <span class="p">(</span><span class="sh">'</span><span class="s">Pamuk</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">renk</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">beyaz</span><span class="sh">'</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">sorgula</span><span class="p">(</span><span class="n">özne</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">ilişki</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">nesne</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span>
    <span class="n">sonuçlar</span> <span class="o">=</span> <span class="p">[]</span>
    <span class="k">for</span> <span class="n">fact</span> <span class="ow">in</span> <span class="n">facts</span><span class="p">:</span>
        <span class="n">o</span><span class="p">,</span> <span class="n">r</span><span class="p">,</span> <span class="n">n</span> <span class="o">=</span> <span class="n">fact</span>
        <span class="k">if</span> <span class="n">özne</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">o</span> <span class="o">!=</span> <span class="n">özne</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="k">if</span> <span class="n">ilişki</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">r</span> <span class="o">!=</span> <span class="n">ilişki</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="k">if</span> <span class="n">nesne</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">None</span> <span class="ow">and</span> <span class="n">n</span> <span class="o">!=</span> <span class="n">nesne</span><span class="p">:</span>
            <span class="k">continue</span>
        <span class="n">sonuçlar</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="n">fact</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">sonuçlar</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">sorgula</span><span class="p">(</span><span class="n">özne</span><span class="o">=</span><span class="sh">'</span><span class="s">Pamuk</span><span class="sh">'</span><span class="p">))</span>
</code></pre></div></div>

<p>Bu kodun amacı, bilgi tabanındaki gerçekleri filtrelemektir. <code class="language-plaintext highlighter-rouge">Pamuk</code> hakkında ne biliyoruz diye sorduğumuzda sistem, onun türünü ve rengini döndürür. Henüz akıl yürütme yoktur; yalnızca kayıtlı gerçekler aranır. Ancak bu temel yapı üzerine kurallar eklendiğinde işler eğlenceli hale gelir.</p>

<p>Bir kuralı matematiksel olarak şöyle düşünebiliriz:</p>

<p>$kedi(x) \Rightarrow memeli(x)$</p>

<p>Bu ifade “Eğer x bir kediyse, x memelidir” der. <code class="language-plaintext highlighter-rouge">Pamuk</code> için $kedi(Pamuk)$ gerçeği varsa, sistem $memeli(Pamuk)$ sonucunu çıkarabilir. Buna çıkarım denir. Bilgi tabanı + kurallar = basit bir mantık motoru.</p>

<table>
  <thead>
    <tr>
      <th>Veri Tabanı</th>
      <th>Bilgi Tabanı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Kayıt saklamaya odaklanır</td>
      <td>Anlam ve çıkarıma odaklanır</td>
    </tr>
    <tr>
      <td>Sorgular çoğunlukla doğrudandır</td>
      <td>Sorgular kurallarla genişleyebilir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SELECT * FROM hayvanlar</code></td>
      <td><code class="language-plaintext highlighter-rouge">kedi(X) -&gt; memeli(X)</code></td>
    </tr>
    <tr>
      <td>Daha çok operasyonel sistemlerde kullanılır</td>
      <td>Yapay zekâ, uzman sistemler ve semantik web’de kullanılır</td>
    </tr>
  </tbody>
</table>

<p>Gerçeklerin kesin ve değişmez olması özellikle önemlidir. “Bugün hava sıcak” gibi bağlama bağlı ifadeler bilgi tabanına eklenebilir ama zaman, yer veya koşul belirtilmezse sorun çıkarır. Daha sağlam bir ifade şöyle olur: <code class="language-plaintext highlighter-rouge">sıcaklık(İstanbul, 2026-07-11, 30)</code>. Böylece gerçek, ölçülebilir ve izlenebilir hale gelir.</p>

<p>Bilgi tabanları; uzman sistemlerde hastalık teşhisi, oyun yapay zekâsında karakter davranışları, semantik aramada kavram ilişkileri ve robotikte çevre modelleme için kullanılır. Bir robotun “masa mutfaktadır” ve “bardak masanın üzerindedir” bilgilerini bilmesi, bardağı bulmak için mutfağa gitmesini sağlayabilir.</p>

<p>Özetle gerçekler, yazılıma dünyanın LEGO parçalarını verir. Kurallar ise bu parçaları nasıl birleştireceğini anlatır. İyi tasarlanmış bir bilgi tabanı, sadece bilgi depolayan değil, bildiklerinden sonuç çıkarabilen sistemlerin temelidir. Yani küçük gerçekler, doğru kurallarla birleştiğinde oldukça zeki davranışların kapısını aralar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="bilgi-tabanı" /><category term="yapay-zeka" /><category term="mantıksal-programlama" /><summary type="html"><![CDATA[Bir yazılıma dünyayı öğretmek isteseydik nereden başlardık? Kedilerin memeli olduğu, Ankara’nın Türkiye’nin başkenti olduğu, suyun 0°C’de donduğu gibi kesin kabul ettiğimiz küçük bilgi parçacıklarıyla. İşte bu küçük, değişmez ve doğrulanabilir ifadelere yapay zekâ ve mantıksal sistemlerde “gerçek” denir. Gerçekler bir araya geldiğinde ise yazılımın akıl yürütebileceği bir bilgi tabanı oluşur.]]></summary></entry><entry><title type="html">JavaScript ile Üç Boyutlu Veri Görselleştirme: Veriyi Ekrandan Taşırmak</title><link href="https://sonsuzus.github.io/posts/javascript-ile-uc-boyutlu-veri-gorsellestirme-veriyi-ekrandan-tasirmak/" rel="alternate" type="text/html" title="JavaScript ile Üç Boyutlu Veri Görselleştirme: Veriyi Ekrandan Taşırmak" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/javascript-ile-uc-boyutlu-veri-gorsellestirme-veriyi-ekrandan-tasirmak</id><content type="html" xml:base="https://sonsuzus.github.io/posts/javascript-ile-uc-boyutlu-veri-gorsellestirme-veriyi-ekrandan-tasirmak/"><![CDATA[<p>Bir tablo düşünün: binlerce satır, onlarca metrik, ilişkiler, kümeler ve zaman değişimleri… Excel bile iç çekiyor. İşte JavaScript ile üç boyutlu veri görselleştirme, bu karmaşayı döndürülebilir, yakınlaştırılabilir ve keşfedilebilir bir sahneye çevirir. Kullanıcı yalnızca grafiğe bakmaz; grafiğin içinde gezinir, düğümlere tıklar, kümeleri ayırır ve istatistiğin sakladığı hikâyeyi daha sezgisel biçimde yakalar.
``</p>

<h2 id="neden-3d-görselleştirme">Neden 3D Görselleştirme?</h2>

<p>Klasik 2D grafikler çoğu durumda harikadır; çizgi grafikler trendleri, sütun grafikler karşılaştırmaları, pasta grafikler oranları gösterir. Fakat veri çok boyutlu hale geldiğinde işler zorlaşır. Örneğin bir müşteri veri setinde yaş, gelir, satın alma sıklığı, lokasyon ve sosyal ağ bağlantıları aynı anda incelenmek istenebilir. 3D sahnede üç değişken eksenlere yerleştirilirken renk, boyut, parlaklık veya animasyonla ek değişkenler temsil edilebilir.</p>

<p>Basit bir eşleme şöyle düşünülebilir: veri noktası $d = (a, b, c)$ ise sahnedeki konumu $p = (x, y, z)$ olur. Ölçekleme genellikle şu mantıkla yapılır: $x = (a - minA) / (maxA - minA)$. Böylece farklı aralıklardaki değerler aynı görsel evrene taşınır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Güçlü Yön</th>
      <th>Zayıf Yön</th>
      <th>Uygun Kullanım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>2D Grafik</td>
      <td>Hızlı anlaşılır</td>
      <td>Boyut sayısı sınırlı</td>
      <td>Raporlar, dashboardlar</td>
    </tr>
    <tr>
      <td>3D Grafik</td>
      <td>Çok değişkenli keşif</td>
      <td>Yanlış tasarlanırsa kafa karıştırır</td>
      <td>Ağlar, kümeler, uzamsal veriler</td>
    </tr>
    <tr>
      <td>Etkileşimli 3D</td>
      <td>Kullanıcı keşfi sağlar</td>
      <td>Performans optimizasyonu ister</td>
      <td>Büyük veri analizi, simülasyon</td>
    </tr>
  </tbody>
</table>

<h2 id="temel-teori-sahne-kamera-nesne">Temel Teori: Sahne, Kamera, Nesne</h2>

<p>Web tarafında 3D denince akla genellikle WebGL gelir. WebGL güçlüdür ama ham haliyle biraz dikenlidir. Bu yüzden Three.js gibi kütüphaneler kullanılır. Three.js dünyasında üç temel karakter vardır: sahne, kamera ve renderer. Sahne evrenin kendisidir, kamera kullanıcının gözüdür, renderer ise bu evreni ekrana çizen motordur.</p>

<p>Veri noktalarını kürelerle göstermek yaygın bir yaklaşımdır. Ağ görselleştirmelerinde düğümler küre, bağlantılar çizgi olarak modellenir. Bir düğümün büyüklüğü derece merkeziliğini gösterebilir. Örneğin bir ağda düğümün bağlantı sayısı $k$ ise yarıçap $r = sqrt(k)$ seçilebilir. Bu sayede çok bağlantılı düğümler görünür olur ama sahneyi ezmez.</p>

<h2 id="mini-threejs-örneği">Mini Three.js Örneği</h2>

<p>Aşağıdaki kod, veri noktalarını üç boyutlu uzayda küçük küreler olarak yerleştirir. Mantık şudur: her veri satırı bir konuma çevrilir, ardından sahneye mesh olarak eklenir.</p>

<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">import</span> <span class="o">*</span> <span class="nx">as</span> <span class="nx">THREE</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">three</span><span class="dl">'</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">scene</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">Scene</span><span class="p">();</span>
<span class="kd">const</span> <span class="nx">camera</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">PerspectiveCamera</span><span class="p">(</span><span class="mi">60</span><span class="p">,</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span> <span class="o">/</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerHeight</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">,</span> <span class="mi">1000</span><span class="p">);</span>
<span class="kd">const</span> <span class="nx">renderer</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">WebGLRenderer</span><span class="p">({</span> <span class="na">antialias</span><span class="p">:</span> <span class="kc">true</span> <span class="p">});</span>
<span class="nx">renderer</span><span class="p">.</span><span class="nf">setSize</span><span class="p">(</span><span class="nb">window</span><span class="p">.</span><span class="nx">innerWidth</span><span class="p">,</span> <span class="nb">window</span><span class="p">.</span><span class="nx">innerHeight</span><span class="p">);</span>
<span class="nb">document</span><span class="p">.</span><span class="nx">body</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">renderer</span><span class="p">.</span><span class="nx">domElement</span><span class="p">);</span>

<span class="nx">camera</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nx">z</span> <span class="o">=</span> <span class="mi">80</span><span class="p">;</span>

<span class="kd">const</span> <span class="nx">data</span> <span class="o">=</span> <span class="p">[</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">10</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">25</span><span class="p">,</span> <span class="na">z</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">12</span> <span class="p">},</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="o">-</span><span class="mi">20</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="na">z</span><span class="p">:</span> <span class="mi">15</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">30</span> <span class="p">},</span>
  <span class="p">{</span> <span class="na">x</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="o">-</span><span class="mi">15</span><span class="p">,</span> <span class="na">z</span><span class="p">:</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span> <span class="na">value</span><span class="p">:</span> <span class="mi">18</span> <span class="p">}</span>
<span class="p">];</span>

<span class="kd">const</span> <span class="nx">material</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">MeshStandardMaterial</span><span class="p">({</span> <span class="na">color</span><span class="p">:</span> <span class="mh">0x44aaff</span> <span class="p">});</span>
<span class="kd">const</span> <span class="nx">light</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">PointLight</span><span class="p">(</span><span class="mh">0xffffff</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
<span class="nx">light</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="mi">40</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">40</span><span class="p">);</span>
<span class="nx">scene</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="nx">light</span><span class="p">);</span>

<span class="nx">data</span><span class="p">.</span><span class="nf">forEach</span><span class="p">(</span><span class="nx">item</span> <span class="o">=&gt;</span> <span class="p">{</span>
  <span class="kd">const</span> <span class="nx">radius</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nf">sqrt</span><span class="p">(</span><span class="nx">item</span><span class="p">.</span><span class="nx">value</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">geometry</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">SphereGeometry</span><span class="p">(</span><span class="nx">radius</span><span class="p">,</span> <span class="mi">24</span><span class="p">,</span> <span class="mi">24</span><span class="p">);</span>
  <span class="kd">const</span> <span class="nx">point</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">THREE</span><span class="p">.</span><span class="nc">Mesh</span><span class="p">(</span><span class="nx">geometry</span><span class="p">,</span> <span class="nx">material</span><span class="p">);</span>
  <span class="nx">point</span><span class="p">.</span><span class="nx">position</span><span class="p">.</span><span class="nf">set</span><span class="p">(</span><span class="nx">item</span><span class="p">.</span><span class="nx">x</span><span class="p">,</span> <span class="nx">item</span><span class="p">.</span><span class="nx">y</span><span class="p">,</span> <span class="nx">item</span><span class="p">.</span><span class="nx">z</span><span class="p">);</span>
  <span class="nx">scene</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="nx">point</span><span class="p">);</span>
<span class="p">});</span>

<span class="kd">function</span> <span class="nf">animate</span><span class="p">()</span> <span class="p">{</span>
  <span class="nf">requestAnimationFrame</span><span class="p">(</span><span class="nx">animate</span><span class="p">);</span>
  <span class="nx">scene</span><span class="p">.</span><span class="nx">rotation</span><span class="p">.</span><span class="nx">y</span> <span class="o">+=</span> <span class="mf">0.003</span><span class="p">;</span>
  <span class="nx">renderer</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="nx">scene</span><span class="p">,</span> <span class="nx">camera</span><span class="p">);</span>
<span class="p">}</span>

<span class="nf">animate</span><span class="p">();</span>
</code></pre></div></div>

<p>Bu örnekte <code class="language-plaintext highlighter-rouge">value</code> alanı kürenin boyutunu belirler. Büyük değerler büyük kürelere dönüşür. Gerçek projelerde renk skalası, tooltip, tıklama olayları ve filtreleme eklenerek grafik çok daha bilgilendirici hale gelir.</p>

<h2 id="etkileşim-neden-kritik">Etkileşim Neden Kritik?</h2>

<p>3D görselleştirmede kullanıcı kontrolü yoksa sahne kısa sürede süslü bir akvaryuma dönüşebilir. OrbitControls ile döndürme, raycasting ile tıklanan nesneyi bulma ve filtre panelleri ile veri katmanlarını açıp kapatma önemlidir.</p>

<table>
  <thead>
    <tr>
      <th>Etkileşim</th>
      <th>Kullanıcıya Katkısı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Döndürme</td>
      <td>Kümelerin arkasındaki yapıyı görür</td>
    </tr>
    <tr>
      <td>Yakınlaştırma</td>
      <td>Yoğun bölgeleri inceler</td>
    </tr>
    <tr>
      <td>Tooltip</td>
      <td>Noktanın ham değerlerini okur</td>
    </tr>
    <tr>
      <td>Filtreleme</td>
      <td>Gürültüyü azaltır</td>
    </tr>
  </tbody>
</table>

<h2 id="performans-ve-tasarım-i̇puçları">Performans ve Tasarım İpuçları</h2>

<p>Her veri noktası ayrı mesh olursa binlerce nesnede performans düşebilir. Bu durumda InstancedMesh, BufferGeometry veya veri ön işleme teknikleri kullanılmalıdır. Ayrıca 3D her zaman daha iyi değildir. Eğer iki değişken anlatılacaksa 2D daha temizdir. 3D, gerçekten üçüncü boyut anlam katıyorsa kullanılmalıdır.</p>

<p>Sonuç olarak JavaScript, tarayıcıyı küçük bir veri laboratuvarına dönüştürür. Three.js, D3.js ve WebGL ekosistemiyle karmaşık istatistikleri yalnızca göstermek değil, yaşatmak mümkündür. Doğru ölçekleme, bilinçli görsel kodlama ve güçlü etkileşim birleştiğinde kullanıcılar veriye bakmaz; veriyle sohbet eder.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="JavaScript" /><category term="Three.js" /><category term="Veri Görselleştirme" /><category term="3D Grafik" /><summary type="html"><![CDATA[Bir tablo düşünün: binlerce satır, onlarca metrik, ilişkiler, kümeler ve zaman değişimleri… Excel bile iç çekiyor. İşte JavaScript ile üç boyutlu veri görselleştirme, bu karmaşayı döndürülebilir, yakınlaştırılabilir ve keşfedilebilir bir sahneye çevirir. Kullanıcı yalnızca grafiğe bakmaz; grafiğin içinde gezinir, düğümlere tıklar, kümeleri ayırır ve istatistiğin sakladığı hikâyeyi daha sezgisel biçimde yakalar.]]></summary></entry><entry><title type="html">Kurallar ve Mantıksal Çıkarım: Eğer-Öyleyse Düşünmenin Programlanabilir Hali</title><link href="https://sonsuzus.github.io/posts/kurallar-ve-mantiksal-cikarim-eger-oyleyse-dusunmenin-programlanabilir-hali/" rel="alternate" type="text/html" title="Kurallar ve Mantıksal Çıkarım: Eğer-Öyleyse Düşünmenin Programlanabilir Hali" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/kurallar-ve-mantiksal-cikarim-eger-oyleyse-dusunmenin-programlanabilir-hali</id><content type="html" xml:base="https://sonsuzus.github.io/posts/kurallar-ve-mantiksal-cikarim-eger-oyleyse-dusunmenin-programlanabilir-hali/"><![CDATA[<p>Bilgisayara akıl yürütmeyi öğretmek ilk bakışta bilim kurgu gibi durabilir; ama işin temelinde oldukça tanıdık bir yapı vardır: eğer bir koşul doğruysa, o koşuldan yeni bir sonuç çıkar. Kurallar ve mantıksal çıkarım, önceden tanımlanmış gerçekleri referans alarak yeni bilgiler üretmemizi sağlar. Yani sistem, elindeki bilgi kartlarını karıştırır, eşleşenleri bulur ve mantıklı yeni kartlar üretir.
``
Günlük hayatta bunu sürekli yaparız. Eğer gökyüzü kapalıysa ve hava serinse, yağmur yağabilir diye düşünürüz. Eğer yağmur yağıyorsa, zeminin ıslak olacağını tahmin ederiz. Kural tabanlı sistemlerde bu düşünce biçimi daha resmi hale getirilir. Bir kural genellikle şu biçimdedir:</p>

<p>$A \rightarrow B$</p>

<p>Burada $A$ koşul, $B$ ise sonuçtur. Anlamı şudur: Eğer $A$ doğruysa, $B$ de doğru kabul edilebilir. Daha karmaşık kurallarda birden fazla koşul bulunabilir:</p>

\[A \land B \rightarrow C\]

<p>Bu ifade, hem $A$ hem de $B$ doğruysa $C$ sonucuna ulaşılır demektir. Buradaki $\land$ sembolü mantıksal ve anlamına gelir.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Anlamı</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Gerçek</td>
      <td>Sistemin doğru bildiği bilgi</td>
      <td>hava_yağmurlu</td>
    </tr>
    <tr>
      <td>Kural</td>
      <td>Koşul-sonuç ilişkisi</td>
      <td>hava_yağmurlu ise zemin_ıslak</td>
    </tr>
    <tr>
      <td>Çıkarım</td>
      <td>Yeni bilgi üretme süreci</td>
      <td>zemin_ıslak sonucuna varmak</td>
    </tr>
    <tr>
      <td>Bilgi tabanı</td>
      <td>Gerçekler ve kurallar bütünü</td>
      <td>tüm kurallar listesi</td>
    </tr>
  </tbody>
</table>

<p>Mantıksal çıkarımın iki popüler yöntemi vardır: ileri zincirleme ve geri zincirleme. İleri zincirleme, eldeki gerçeklerden başlayıp mümkün olan tüm sonuçları üretmeye çalışır. Geri zincirleme ise hedef bir sonucun doğru olup olmadığını kanıtlamaya çalışır. Dedektif benzetmesiyle düşünürsek, ileri zincirleme olay yerindeki tüm ipuçlarını inceleyip sonuçlara gider; geri zincirleme ise önce şüpheliyi seçer, sonra kanıt arar.</p>

<table>
  <thead>
    <tr>
      <th>Yöntem</th>
      <th>Başlangıç Noktası</th>
      <th>Kullanım Alanı</th>
      <th>Mantık</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>İleri zincirleme</td>
      <td>Mevcut gerçekler</td>
      <td>Simülasyon, uzman sistem</td>
      <td>Bildiklerimden ne çıkar?</td>
    </tr>
    <tr>
      <td>Geri zincirleme</td>
      <td>Hedef sonuç</td>
      <td>Tanı sistemleri, sorgulama</td>
      <td>Bu sonucu kanıtlayabilir miyim?</td>
    </tr>
  </tbody>
</table>

<p>Basit bir ileri zincirleme motoru Python ile şöyle modellenebilir:</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">facts</span> <span class="o">=</span> <span class="p">{</span><span class="sh">'</span><span class="s">hava_yagmurlu</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">bulutlu</span><span class="sh">'</span><span class="p">}</span>

<span class="n">rules</span> <span class="o">=</span> <span class="p">[</span>
    <span class="p">({</span><span class="sh">'</span><span class="s">hava_yagmurlu</span><span class="sh">'</span><span class="p">},</span> <span class="sh">'</span><span class="s">zemin_islak</span><span class="sh">'</span><span class="p">),</span>
    <span class="p">({</span><span class="sh">'</span><span class="s">zemin_islak</span><span class="sh">'</span><span class="p">},</span> <span class="sh">'</span><span class="s">kayma_riski</span><span class="sh">'</span><span class="p">),</span>
    <span class="p">({</span><span class="sh">'</span><span class="s">bulutlu</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">hava_yagmurlu</span><span class="sh">'</span><span class="p">},</span> <span class="sh">'</span><span class="s">semsiye_gerekli</span><span class="sh">'</span><span class="p">)</span>
<span class="p">]</span>

<span class="k">def</span> <span class="nf">forward_chain</span><span class="p">(</span><span class="n">facts</span><span class="p">,</span> <span class="n">rules</span><span class="p">):</span>
    <span class="n">changed</span> <span class="o">=</span> <span class="bp">True</span>
    <span class="k">while</span> <span class="n">changed</span><span class="p">:</span>
        <span class="n">changed</span> <span class="o">=</span> <span class="bp">False</span>
        <span class="k">for</span> <span class="n">conditions</span><span class="p">,</span> <span class="n">result</span> <span class="ow">in</span> <span class="n">rules</span><span class="p">:</span>
            <span class="k">if</span> <span class="n">conditions</span><span class="p">.</span><span class="nf">issubset</span><span class="p">(</span><span class="n">facts</span><span class="p">)</span> <span class="ow">and</span> <span class="n">result</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">facts</span><span class="p">:</span>
                <span class="n">facts</span><span class="p">.</span><span class="nf">add</span><span class="p">(</span><span class="n">result</span><span class="p">)</span>
                <span class="n">changed</span> <span class="o">=</span> <span class="bp">True</span>
                <span class="nf">print</span><span class="p">(</span><span class="sh">'</span><span class="s">Yeni sonuc:</span><span class="sh">'</span><span class="p">,</span> <span class="n">result</span><span class="p">)</span>
    <span class="k">return</span> <span class="n">facts</span>

<span class="n">final_facts</span> <span class="o">=</span> <span class="nf">forward_chain</span><span class="p">(</span><span class="n">facts</span><span class="p">,</span> <span class="n">rules</span><span class="p">)</span>
<span class="nf">print</span><span class="p">(</span><span class="n">final_facts</span><span class="p">)</span>
</code></pre></div></div>

<p>Bu kodda <code class="language-plaintext highlighter-rouge">facts</code> başlangıçta doğru kabul edilen bilgileri tutar. <code class="language-plaintext highlighter-rouge">rules</code> listesinde ise her kuralın koşulları ve sonucu vardır. <code class="language-plaintext highlighter-rouge">issubset</code> kontrolü, kuralın tüm koşullarının mevcut gerçekler içinde olup olmadığını denetler. Eğer koşullar sağlanıyorsa sonuç bilgi tabanına eklenir. Döngü, artık yeni bilgi üretilemeyene kadar devam eder.</p>

<p>Bu yaklaşımın en güzel tarafı açıklanabilir olmasıdır. Bir sinir ağı bazen neden öyle karar verdiğini anlatmakta zorlanırken, kural tabanlı sistemlerde karar zinciri izlenebilir: Yağmur yağdı, bu yüzden zemin ıslandı; zemin ıslandı, bu yüzden kayma riski oluştu. Gayet dedikoducu ama şeffaf bir sistem!</p>

<p>Elbette kuralların da sınırları vardır. Çok fazla kural olduğunda çakışmalar ortaya çıkabilir. Örneğin bir kural klima aç derken başka bir kural pencere aç diyebilir. Bu durumda önceliklendirme, ağırlıklandırma veya çatışma çözme stratejileri gerekir. Bazen kurallara güven derecesi de eklenir. Mesela $P(yağmur)=0.8$ gibi olasılıksal ifadelerle sistem daha esnek hale getirilebilir.</p>

<p>Sonuç olarak kurallar ve mantıksal çıkarım, yapay zekanın en anlaşılır yapı taşlarından biridir. Veriyi ezberlemek yerine, bilgiden bilgi üretmeyi sağlar. Küçük bir eğer-öyleyse cümlesi, doğru bağlandığında koca bir karar mekanizmasına dönüşebilir. Yazılım dünyasında bu yapı; uzman sistemlerden oyun yapay zekasına, iş kurallarından otomasyon senaryolarına kadar birçok yerde sessizce çalışır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="mantıksal çıkarım" /><category term="kural tabanlı sistemler" /><category term="yapay zeka" /><summary type="html"><![CDATA[Bilgisayara akıl yürütmeyi öğretmek ilk bakışta bilim kurgu gibi durabilir; ama işin temelinde oldukça tanıdık bir yapı vardır: eğer bir koşul doğruysa, o koşuldan yeni bir sonuç çıkar. Kurallar ve mantıksal çıkarım, önceden tanımlanmış gerçekleri referans alarak yeni bilgiler üretmemizi sağlar. Yani sistem, elindeki bilgi kartlarını karıştırır, eşleşenleri bulur ve mantıklı yeni kartlar üretir.]]></summary></entry></feed>