<?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-18T14:48:45+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">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><entry><title type="html">Prolog Kurulumu ve VS Code ile İlk Geliştirme Ortamı</title><link href="https://sonsuzus.github.io/posts/prolog-kurulumu-ve-vs-code-ile-ilk-gelistirme-ortami/" rel="alternate" type="text/html" title="Prolog Kurulumu ve VS Code ile İlk Geliştirme Ortamı" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/prolog-kurulumu-ve-vs-code-ile-ilk-gelistirme-ortami</id><content type="html" xml:base="https://sonsuzus.github.io/posts/prolog-kurulumu-ve-vs-code-ile-ilk-gelistirme-ortami/"><![CDATA[<p>Prolog, programcıya “nasıl yapılır?” yerine “ne doğrudur?” diye sorduran hoş bir zihin jimnastiğidir. Bu yazıda SWI-Prolog kurulumunu tamamlayacak, derleyici/yorumlayıcı ayarlarını kontrol edecek ve VS Code üzerinde teorik bilgiyi pratiğe dökeceğimiz küçük bir laboratuvar hazırlayacağız.
``</p>

<h2 id="prologun-kafası-nasıl-çalışır">Prolog’un Kafası Nasıl Çalışır?</h2>

<p>Prolog, mantıksal programlama ailesindendir. Program; <strong>olgular</strong>, <strong>kurallar</strong> ve <strong>sorgular</strong> üzerine kurulur. Klasik dillerde akış çoğunlukla yukarıdan aşağıya komutlarla ilerlerken, Prolog hedefe ulaşmak için kuralları dener, eşleştirme yapar ve gerekirse geri izleme, yani <strong>backtracking</strong>, uygular.</p>

<p>Bir Prolog kuralını kabaca şöyle düşünebiliriz:</p>

<p>$H \leftarrow B_1 \land B_2 \land … \land B_n$</p>

<p>Yani “$H$ doğrudur, eğer tüm $B$ koşulları doğruysa.” Prolog’da bu yapı şöyle yazılır:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">ata</span><span class="p">(</span><span class="ss">ahmet</span><span class="p">,</span> <span class="ss">mehmet</span><span class="p">).</span>
<span class="ss">ata</span><span class="p">(</span><span class="ss">mehmet</span><span class="p">,</span> <span class="ss">zeynep</span><span class="p">).</span>

<span class="ss">dede</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">ata</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="nv">Z</span><span class="p">),</span> <span class="ss">ata</span><span class="p">(</span><span class="nv">Z</span><span class="p">,</span> <span class="nv">Y</span><span class="p">).</span>
</code></pre></div></div>

<p>Bu kodda ilk iki satır <strong>olgu</strong>, son satır ise <strong>kuraldır</strong>. <code class="language-plaintext highlighter-rouge">dede(X, Y)</code> sorgusu için Prolog, uygun <code class="language-plaintext highlighter-rouge">Z</code> değerini arar. Değişkenler büyük harfle başlar; <code class="language-plaintext highlighter-rouge">X</code>, <code class="language-plaintext highlighter-rouge">Y</code>, <code class="language-plaintext highlighter-rouge">Z</code> birer bilinmeyendir. Eşleştirme işleminde Prolog bir yerine koyma bulur; buna $\theta = {X/ahmet, Y/zeynep}$ gibi bakabiliriz.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Prolog’daki Karşılığı</th>
      <th>Sezgisel Anlamı</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Olgu</td>
      <td><code class="language-plaintext highlighter-rouge">ata(ahmet, mehmet).</code></td>
      <td>Veritabanındaki kesin bilgi</td>
    </tr>
    <tr>
      <td>Kural</td>
      <td><code class="language-plaintext highlighter-rouge">dede(X,Y) :- ...</code></td>
      <td>Koşullu mantıksal çıkarım</td>
    </tr>
    <tr>
      <td>Sorgu</td>
      <td><code class="language-plaintext highlighter-rouge">?- dede(ahmet, zeynep).</code></td>
      <td>“Bu doğru mu?” sorusu</td>
    </tr>
    <tr>
      <td>Backtracking</td>
      <td>Alternatifleri deneme</td>
      <td>Dedektif gibi iz sürme</td>
    </tr>
  </tbody>
</table>

<h2 id="swi-prolog-kurulumu">SWI-Prolog Kurulumu</h2>

<p>Modern Prolog geliştirme için en pratik seçeneklerden biri <strong>SWI-Prolog</strong>’dur. Windows, macOS ve Linux üzerinde çalışır, paket yöneticileriyle kolay kurulur ve VS Code ile iyi anlaşır.</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># macOS</span>
brew <span class="nb">install </span>swi-prolog

<span class="c"># Ubuntu/Debian</span>
<span class="nb">sudo </span>apt update
<span class="nb">sudo </span>apt <span class="nb">install </span>swi-prolog
</code></pre></div></div>

<p>Bu komutlar SWI-Prolog yorumlayıcısını sisteminize kurar. Kurulumdan sonra terminalde şu komutla kontrol edebilirsiniz:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>swipl <span class="nt">--version</span>
</code></pre></div></div>

<p>Eğer sürüm bilgisi görüyorsanız, derleyici/yorumlayıcı yolu başarıyla yapılandırılmış demektir. Windows’ta kurulum sihirbazında <strong>Add swipl to PATH</strong> benzeri seçeneği işaretlemek önemlidir. İşaretlemediyseniz, SWI-Prolog’un <code class="language-plaintext highlighter-rouge">bin</code> klasörünü sistem PATH değişkenine elle eklemeniz gerekir.</p>

<h2 id="vs-code-ortamını-hazırlama">VS Code Ortamını Hazırlama</h2>

<p>VS Code tarafında amaç; dosya düzenleme, sözdizimi renklendirme ve terminal üzerinden hızlı çalıştırma konforunu sağlamaktır. Eklentiler bölümünden <strong>VSC-Prolog</strong> veya güncel Prolog sözdizimi desteği sunan bir uzantı kurabilirsiniz.</p>

<table>
  <thead>
    <tr>
      <th>Bileşen</th>
      <th>Görev</th>
      <th>Neden Gerekli?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>SWI-Prolog</td>
      <td>Programı çalıştırır</td>
      <td>Mantık motoru burada</td>
    </tr>
    <tr>
      <td>VS Code</td>
      <td>Kod editörü</td>
      <td>Rahat yazma ve gezinme</td>
    </tr>
    <tr>
      <td>Prolog eklentisi</td>
      <td>Renklendirme sağlar</td>
      <td>Hataları daha hızlı fark ettirir</td>
    </tr>
    <tr>
      <td>Entegre terminal</td>
      <td>Sorgu çalıştırır</td>
      <td>Editörden çıkmadan test</td>
    </tr>
  </tbody>
</table>

<p>Proje klasörünüzü açın ve <code class="language-plaintext highlighter-rouge">aile.pl</code> adında bir dosya oluşturun:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">kadın</span><span class="p">(</span><span class="ss">ayse</span><span class="p">).</span>
<span class="ss">erkek</span><span class="p">(</span><span class="ss">ali</span><span class="p">).</span>
<span class="ss">ebeveyn</span><span class="p">(</span><span class="ss">ayse</span><span class="p">,</span> <span class="ss">ali</span><span class="p">).</span>

<span class="ss">anne</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">kadın</span><span class="p">(</span><span class="nv">X</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>Bu dosya basit bir bilgi tabanı kurar. <code class="language-plaintext highlighter-rouge">anne(X, Y)</code> kuralı, <code class="language-plaintext highlighter-rouge">X</code> kişisinin kadın ve <code class="language-plaintext highlighter-rouge">Y</code> kişisinin ebeveyni olup olmadığını kontrol eder.</p>

<p>Terminalde dosyayı şu şekilde yükleyin:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>swipl aile.pl
</code></pre></div></div>

<p>Ardından Prolog etkileşimli kabuğunda sorgu yazabilirsiniz:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">?-</span> <span class="ss">anne</span><span class="p">(</span><span class="ss">ayse</span><span class="p">,</span> <span class="ss">ali</span><span class="p">).</span>
<span class="o">?-</span> <span class="ss">anne</span><span class="p">(</span><span class="nv">Kim</span><span class="p">,</span> <span class="ss">ali</span><span class="p">).</span>
</code></pre></div></div>

<p>İlk sorgu doğruysa <code class="language-plaintext highlighter-rouge">true.</code> döner. İkinci sorguda Prolog değişkeni doldurmaya çalışır ve <code class="language-plaintext highlighter-rouge">Kim = ayse.</code> gibi bir cevap üretir.</p>

<h2 id="i̇lk-ayar-kontrol-listesi">İlk Ayar Kontrol Listesi</h2>

<p>Kurulumda sorun yaşarsanız şu küçük liste hayat kurtarır:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">swipl --version</code> çalışıyor mu?</li>
  <li><code class="language-plaintext highlighter-rouge">.pl</code> dosyası doğru klasörde mi?</li>
  <li>VS Code terminali aynı proje dizininde mi açıldı?</li>
  <li>Dosyadaki her olgu ve kural nokta ile bitiyor mu?</li>
  <li>Değişkenler büyük harfle, atomlar küçük harfle mi başlıyor?</li>
</ul>

<p>Prolog öğrenirken en güzel yöntem, küçük bilgi tabanları kurup bol bol sorgu sormaktır. Çünkü Prolog’da program yazmak biraz şehir haritası çizmek gibidir: yolları siz tanımlarsınız, hedefe giden rotayı mantık motoru bulur.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="prolog" /><category term="swi-prolog" /><category term="vscode" /><category term="mantıksal-programlama" /><summary type="html"><![CDATA[Prolog, programcıya “nasıl yapılır?” yerine “ne doğrudur?” diye sorduran hoş bir zihin jimnastiğidir. Bu yazıda SWI-Prolog kurulumunu tamamlayacak, derleyici/yorumlayıcı ayarlarını kontrol edecek ve VS Code üzerinde teorik bilgiyi pratiğe dökeceğimiz küçük bir laboratuvar hazırlayacağız.]]></summary></entry><entry><title type="html">Prolog Temelleri ve Paradigma Farkları: Emirlerden Mantığa Yolculuk</title><link href="https://sonsuzus.github.io/posts/prolog-temelleri-ve-paradigma-farklari-emirlerden-mantiga-yolculuk/" rel="alternate" type="text/html" title="Prolog Temelleri ve Paradigma Farkları: Emirlerden Mantığa Yolculuk" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/prolog-temelleri-ve-paradigma-farklari-emirlerden-mantiga-yolculuk</id><content type="html" xml:base="https://sonsuzus.github.io/posts/prolog-temelleri-ve-paradigma-farklari-emirlerden-mantiga-yolculuk/"><![CDATA[<p>Bir emirsel dilde bilgisayara adım adım ne yapacağını söylersin; Prolog gibi mantıksal bir dilde ise evrenin kurallarını tarif eder, sonra ona soru sorarsın. Bu küçük fark, programlama zihniyetinde büyük bir deprem yaratır: döngülerden, sayaçlardan ve durum güncellemelerinden uzaklaşıp olgular, kurallar ve çıkarımlar dünyasına gireriz.
``
Prolog, adını Programming in Logic ifadesinden alır ve temel fikri oldukça şiirseldir: Program, çalıştırılacak komut listesi değil, doğru kabul edilen bilgilerin ve bu bilgilerden türetilebilecek sonuçların bir kümesidir. Matematiksel olarak düşünürsek Prolog programını kabaca şöyle görebiliriz: $Program = Olgular + Kurallar$, çalıştırma ise $Sorgu \Rightarrow Kanıt arama$ sürecidir.</p>

<p>Emirsel dillerde geliştirici genellikle belleğin zaman içindeki durumunu yönetir. Değişkenler atanır, döngüler kurulur, koşullar dallanır. Mantıksal programlamada ise amaç, sonucu hangi adımlarla bulacağını tarif etmekten çok, sonucun hangi mantıksal koşullarda doğru olacağını belirtmektir. Bu yüzden Prolog kodu bazen programdan çok küçük bir bilgi tabanı gibi görünür.</p>

<table>
  <thead>
    <tr>
      <th>Özellik</th>
      <th>Emirsel Yaklaşım</th>
      <th>Mantıksal Yaklaşım</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Temel soru</td>
      <td>Nasıl yapılır?</td>
      <td>Ne doğrudur?</td>
    </tr>
    <tr>
      <td>Ana yapı</td>
      <td>Komut, atama, döngü</td>
      <td>Olgu, kural, sorgu</td>
    </tr>
    <tr>
      <td>Kontrol</td>
      <td>Programcı akışı belirler</td>
      <td>Çıkarım motoru arar</td>
    </tr>
    <tr>
      <td>Değişken</td>
      <td>Bellekte değer tutar</td>
      <td>Mantıksal bilinmeyendir</td>
    </tr>
    <tr>
      <td>Hata tipi</td>
      <td>Yanlış algoritma adımı</td>
      <td>Eksik veya hatalı bilgi modeli</td>
    </tr>
  </tbody>
</table>

<p>Prolog’un en küçük yapı taşı olgudur. Olgu, dünyaya dair doğru kabul edilen basit bir cümledir. Örneğin aşağıdaki bilgi tabanı aile ilişkilerini tanımlar:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">% Olgular: Bunlar doğru kabul edilir.</span>
<span class="ss">ebeveyn</span><span class="p">(</span><span class="ss">ayse</span><span class="p">,</span> <span class="ss">mehmet</span><span class="p">).</span>
<span class="ss">ebeveyn</span><span class="p">(</span><span class="ss">mehmet</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="c1">% Kural: X, Y'nin atasıdır; eğer X, Y'nin ebeveyniyse.</span>
<span class="ss">ata</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>

<span class="c1">% Özyinelemeli kural: X, Z'nin atasıdır; eğer X, Y'nin ebeveyni</span>
<span class="c1">% ve Y de Z'nin atasıysa.</span>
<span class="ss">ata</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="nv">Z</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> <span class="ss">ata</span><span class="p">(</span><span class="nv">Y</span><span class="p">,</span> <span class="nv">Z</span><span class="p">).</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">ata(X, Y)</code> klasik anlamda bir fonksiyon değildir. Daha çok, doğru olup olmadığı araştırılan bir ilişkidir. Prolog’a <code class="language-plaintext highlighter-rouge">ata(ayse, deniz).</code> diye sorduğumuzda motor, olguları ve kuralları kullanarak bir kanıt arar. Bu süreçte iki temel mekanizma devrededir: eşleme ve geri izleme.</p>

<p>Eşleme, Prolog’un iki ifadeyi birbirine uygun hale getirmesidir. Örneğin <code class="language-plaintext highlighter-rouge">ebeveyn(ayse, Kim)</code> sorgusunda <code class="language-plaintext highlighter-rouge">Kim = mehmet</code> sonucu bulunur. Geri izleme ise bir çözümden sonra başka çözüm var mı diye alternatif yolları denemesidir. Yani Prolog, küçük bir dedektif gibi ipuçlarını takip eder; çıkmaz sokağa girerse geri dönüp başka kapıyı çalar.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Kısa açıklama</th>
      <th>Emirsel dünyadaki benzetme</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Olgu</td>
      <td>Doğru kabul edilen bilgi</td>
      <td>Sabit veri kaydı</td>
    </tr>
    <tr>
      <td>Kural</td>
      <td>Koşullu mantıksal çıkarım</td>
      <td>if bloğuna benzer ama bildirimsel</td>
    </tr>
    <tr>
      <td>Sorgu</td>
      <td>Cevabı aranan önerme</td>
      <td>Fonksiyon çağrısı gibi görünür</td>
    </tr>
    <tr>
      <td>Eşleme</td>
      <td>Değişkenleri uygun değerlerle bağlama</td>
      <td>Parametre eşleme</td>
    </tr>
    <tr>
      <td>Geri izleme</td>
      <td>Alternatif çözümleri deneme</td>
      <td>Otomatik arama algoritması</td>
    </tr>
  </tbody>
</table>

<p>Bildirimsel felsefenin güzelliği burada ortaya çıkar. Diyelim ki bir liste içinde eleman aramak istiyoruz. Emirsel bir dilde sayaç açar, listenin sonuna kadar gider, karşılaştırma yaparız. Prolog’da ise ilişkinin tanımını yaparız:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">% Eleman, listenin başındaysa üyedir.</span>
<span class="ss">uye</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="p">|</span><span class="nv">_</span><span class="p">]).</span>

<span class="c1">% Değilse, listenin kuyruğunda aranır.</span>
<span class="ss">uye</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="p">[</span><span class="nv">_</span><span class="p">|</span><span class="nv">Kuyruk</span><span class="p">])</span> <span class="p">:-</span> <span class="ss">uye</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="nv">Kuyruk</span><span class="p">).</span>
</code></pre></div></div>

<p>Bu iki satır şunu söyler: Bir şey listenin ilk elemanıysa üyedir; değilse geri kalanında üyeyse yine üyedir. Burada döngü yoktur, sayaç yoktur, indeks yoktur. Yine de Prolog bu tanımı kullanarak hem <code class="language-plaintext highlighter-rouge">uye(3, [1,2,3])</code> sorusuna doğru cevabını verebilir hem de <code class="language-plaintext highlighter-rouge">uye(X, [a,b,c])</code> sorgusuyla olası değerleri tek tek üretebilir.</p>

<p>Elbette Prolog sihirli değnek değildir. Sayısal hesaplama, grafik arayüz, sistem programlama gibi alanlarda emirsel diller daha doğal olabilir. Ancak kural tabanlı sistemler, uzman sistemler, doğal dil işleme, planlama, bulmaca çözme ve sembolik yapay zeka gibi konularda Prolog’un mantıksal modeli çok güçlüdür.</p>

<p>Sonuç olarak Prolog öğrenmek sadece yeni bir dil öğrenmek değildir; programlama hakkında düşünme biçimini genişletmektir. Emirsel paradigmada algoritmayı yürütürüz; mantıksal paradigmada gerçeği tarif ederiz. Birinde bilgisayara yolu çizeriz, diğerinde hedefin tanımını veririz. Ve bazen en zarif program, ne yapılacağını bağıran değil, neyin doğru olduğunu sakin sakin anlatandır.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Prolog" /><category term="Mantıksal Programlama" /><category term="Programlama Paradigmaları" /><summary type="html"><![CDATA[Bir emirsel dilde bilgisayara adım adım ne yapacağını söylersin; Prolog gibi mantıksal bir dilde ise evrenin kurallarını tarif eder, sonra ona soru sorarsın. Bu küçük fark, programlama zihniyetinde büyük bir deprem yaratır: döngülerden, sayaçlardan ve durum güncellemelerinden uzaklaşıp olgular, kurallar ve çıkarımlar dünyasına gireriz.]]></summary></entry><entry><title type="html">Prolog’da Birleştirme (Unification): Mantığın Sessiz Uzlaştırıcısı</title><link href="https://sonsuzus.github.io/posts/prologda-birlestirme-unification-mantigin-sessiz-uzlastiricisi/" rel="alternate" type="text/html" title="Prolog’da Birleştirme (Unification): Mantığın Sessiz Uzlaştırıcısı" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/prologda-birlestirme-unification-mantigin-sessiz-uzlastiricisi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/prologda-birlestirme-unification-mantigin-sessiz-uzlastiricisi/"><![CDATA[<p>Prolog yazarken bazen tek satırlık bir sorgu, sanki arka planda küçük bir dedektif ordusu çalışıyormuş gibi sonuç üretir. İşte bu dedektiflerin en çalışkanı birleştirme, yani unification sürecidir. Birleştirme; iki terimi, değişkeni veya yapıyı, mantıksal olarak aynı hale getirecek değer atamalarını bulma işlemidir. Prolog motoru bunu otomatik yapar ve çoğu zaman biz fark etmeden programın kaderini belirler.
``</p>

<p>Birleştirmeyi basit eşitlikten ayırmak önemlidir. Matematikte $2 + 3 = 5$ gibi bir eşitlik doğruluk kontrolüdür. Prolog’da ise <code class="language-plaintext highlighter-rouge">X = elma</code> dediğimizde çoğu zaman soru şu değildir: Bunlar zaten eşit mi? Asıl soru şudur: Bunları eşit yapmanın bir yolu var mı? Eğer varsa Prolog değişkenlere uygun değerleri bağlar.</p>

<p>Teorik olarak birleştirme, iki terim $T_1$ ve $T_2$ için bir yer değiştirme kümesi, yani $\sigma$ arar. Bu küme uygulandığında $T_1\sigma = T_2\sigma$ oluyorsa işlem başarılıdır. En iyi sonuç ise MGU, yani most general unifier olarak bilinir. Türkçesiyle en genel birleştirici. Bu, gereksiz kısıtlama koymadan iki ifadeyi eşitleyen en esnek çözümdür.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Ne yapar?</th>
      <th>Prolog örneği</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Eşleştirme</td>
      <td>Yapıların uyumuna bakar</td>
      <td><code class="language-plaintext highlighter-rouge">kedi(X)</code> ile <code class="language-plaintext highlighter-rouge">kedi(mavis)</code></td>
    </tr>
    <tr>
      <td>Atama</td>
      <td>Değişkeni değere bağlar</td>
      <td><code class="language-plaintext highlighter-rouge">X = mavis</code></td>
    </tr>
    <tr>
      <td>Birleştirme</td>
      <td>İki tarafı aynı yapacak bağlamayı bulur</td>
      <td><code class="language-plaintext highlighter-rouge">anne(X)</code> ile <code class="language-plaintext highlighter-rouge">anne(ayse)</code></td>
    </tr>
    <tr>
      <td>Başarısızlık</td>
      <td>Uyum mümkün değilse durur</td>
      <td><code class="language-plaintext highlighter-rouge">kedi(X)</code> ile <code class="language-plaintext highlighter-rouge">kopek(X)</code></td>
    </tr>
  </tbody>
</table>

<p>Prolog terimleri üç ana grupta düşünülebilir: atomlar, değişkenler ve bileşik terimler. Atomlar sabit isimlerdir: <code class="language-plaintext highlighter-rouge">ali</code>, <code class="language-plaintext highlighter-rouge">kitap</code>, <code class="language-plaintext highlighter-rouge">mavi</code>. Değişkenler büyük harfle başlar: <code class="language-plaintext highlighter-rouge">X</code>, <code class="language-plaintext highlighter-rouge">Kisi</code>, <code class="language-plaintext highlighter-rouge">Sonuc</code>. Bileşik terimler ise functor ve argümanlardan oluşur: <code class="language-plaintext highlighter-rouge">seviyor(ali, kitap)</code> gibi. Birleştirme bu yapıları katman katman karşılaştırır.</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">% Basit birleştirme örnekleri</span>
<span class="o">?-</span> <span class="nv">X</span> <span class="o">=</span> <span class="ss">elma</span><span class="p">.</span>
<span class="c1">% X = elma</span>

<span class="o">?-</span> <span class="ss">kisi</span><span class="p">(</span><span class="ss">ali</span><span class="p">,</span> <span class="nv">Yas</span><span class="p">)</span> <span class="o">=</span> <span class="ss">kisi</span><span class="p">(</span><span class="ss">ali</span><span class="p">,</span> <span class="m">30</span><span class="p">).</span>
<span class="c1">% Yas = 30</span>

<span class="o">?-</span> <span class="ss">nokta</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="m">5</span><span class="p">)</span> <span class="o">=</span> <span class="ss">nokta</span><span class="p">(</span><span class="m">3</span><span class="p">,</span> <span class="nv">Y</span><span class="p">).</span>
<span class="c1">% X = 3, Y = 5</span>
</code></pre></div></div>

<p>Bu örneklerde Prolog, yapıların adlarına ve argüman sayılarına bakar. <code class="language-plaintext highlighter-rouge">nokta(X, 5)</code> ile <code class="language-plaintext highlighter-rouge">nokta(3, Y)</code> aynı functor adına ve aynı arity değerine sahiptir. Bu yüzden argümanlar sırayla birleştirilir. Önce <code class="language-plaintext highlighter-rouge">X = 3</code>, sonra <code class="language-plaintext highlighter-rouge">5 = Y</code>; sonuçta iki değişken de uygun değerlere bağlanır.</p>

<table>
  <thead>
    <tr>
      <th>Karşılaştırma</th>
      <th style="text-align: right">Başarılı mı?</th>
      <th>Neden</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">X = armut</code></td>
      <td style="text-align: right">Evet</td>
      <td>Değişken serbesttir</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ali = ali</code></td>
      <td style="text-align: right">Evet</td>
      <td>Aynı atomdur</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ali = veli</code></td>
      <td style="text-align: right">Hayır</td>
      <td>Farklı atomlardır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">f(X) = f(10)</code></td>
      <td style="text-align: right">Evet</td>
      <td>Aynı yapı, değişken bağlanır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">f(X) = g(X)</code></td>
      <td style="text-align: right">Hayır</td>
      <td>Functor adları farklıdır</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">f(a,b) = f(a)</code></td>
      <td style="text-align: right">Hayır</td>
      <td>Argüman sayıları farklıdır</td>
    </tr>
  </tbody>
</table>

<p>Birleştirmenin en eğlenceli tarafı, sadece tek bir değişkeni değil, tüm yapıyı dönüştürebilmesidir. Mesela <code class="language-plaintext highlighter-rouge">aile(anne(X), baba(Y))</code> gibi iç içe terimler varsa Prolog en dıştan başlayıp içeri doğru ilerler. Her katmanda aynı soru sorulur: Bu iki şeyi aynı yapabilir miyim?</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">% İç içe yapılarda birleştirme</span>
<span class="o">?-</span> <span class="ss">aile</span><span class="p">(</span><span class="ss">anne</span><span class="p">(</span><span class="nv">X</span><span class="p">),</span> <span class="ss">baba</span><span class="p">(</span><span class="ss">veli</span><span class="p">))</span> <span class="o">=</span> <span class="ss">aile</span><span class="p">(</span><span class="ss">anne</span><span class="p">(</span><span class="ss">ayse</span><span class="p">),</span> <span class="ss">baba</span><span class="p">(</span><span class="nv">Y</span><span class="p">)).</span>
<span class="c1">% X = ayse,</span>
<span class="c1">% Y = veli</span>
</code></pre></div></div>

<p>Burada <code class="language-plaintext highlighter-rouge">aile</code> yapısı eşleşir, sonra <code class="language-plaintext highlighter-rouge">anne(X)</code> ile <code class="language-plaintext highlighter-rouge">anne(ayse)</code> karşılaştırılır. Ardından <code class="language-plaintext highlighter-rouge">baba(veli)</code> ile <code class="language-plaintext highlighter-rouge">baba(Y)</code> birleştirilir. Sonuç, iki küçük bağlamanın birleşimidir: $\sigma = {X/ayse, Y/veli}$.</p>

<p>Bir noktaya dikkat: Prolog’daki <code class="language-plaintext highlighter-rouge">=</code> aritmetik hesap yapmaz, birleştirme yapar. Yani <code class="language-plaintext highlighter-rouge">X = 2 + 3</code> sorgusu <code class="language-plaintext highlighter-rouge">X</code> değişkenini <code class="language-plaintext highlighter-rouge">5</code> değerine değil, <code class="language-plaintext highlighter-rouge">2 + 3</code> terimine bağlar. Hesaplama için genellikle <code class="language-plaintext highlighter-rouge">is</code> kullanılır.</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="o">=</span> <span class="m">2</span> <span class="o">+</span> <span class="m">3</span><span class="p">.</span>
<span class="c1">% X = 2+3</span>

<span class="o">?-</span> <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>

<table>
  <thead>
    <tr>
      <th>Operatör</th>
      <th>Anlamı</th>
      <th>Örnek sonuç</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">=</code></td>
      <td>Birleştirme</td>
      <td><code class="language-plaintext highlighter-rouge">X = 2+3</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">is</code></td>
      <td>Aritmetik değerlendirme</td>
      <td><code class="language-plaintext highlighter-rouge">X is 5</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">==</code></td>
      <td>Aynı terim mi?</td>
      <td>Bağlama yapmaz</td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">\=</code></td>
      <td>Birleştirilemez mi?</td>
      <td>Uyum yoksa başarılı</td>
    </tr>
  </tbody>
</table>

<p>Özetle birleştirme, Prolog’un kalbidir. Kuralların çalışması, sorguların cevaplanması, değişkenlerin anlam kazanması hep bu süreçle olur. Eğer Prolog’u bir bulmaca oyunu gibi düşünürsek, unification parçaları masaya dizen, kenarlarını karşılaştıran ve uygun olanları sessizce birbirine kilitleyen mekanizmadır. Onu anladığınızda Prolog artık sihirli değil; mantıklı, sistemli ve oldukça keyifli görünmeye başlar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="Prolog" /><category term="Mantıksal Programlama" /><category term="Unification" /><summary type="html"><![CDATA[Prolog yazarken bazen tek satırlık bir sorgu, sanki arka planda küçük bir dedektif ordusu çalışıyormuş gibi sonuç üretir. İşte bu dedektiflerin en çalışkanı birleştirme, yani unification sürecidir. Birleştirme; iki terimi, değişkeni veya yapıyı, mantıksal olarak aynı hale getirecek değer atamalarını bulma işlemidir. Prolog motoru bunu otomatik yapar ve çoğu zaman biz fark etmeden programın kaderini belirler.]]></summary></entry><entry><title type="html">Sorgular Mekanizması: Mantık Motoruna Soru Sormanın Eğlenceli Yolu</title><link href="https://sonsuzus.github.io/posts/sorgular-mekanizmasi-mantik-motoruna-soru-sormanin-eglenceli-yolu/" rel="alternate" type="text/html" title="Sorgular Mekanizması: Mantık Motoruna Soru Sormanın Eğlenceli Yolu" /><published>2026-07-18T00:00:00+00:00</published><updated>2026-07-18T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/sorgular-mekanizmasi-mantik-motoruna-soru-sormanin-eglenceli-yolu</id><content type="html" xml:base="https://sonsuzus.github.io/posts/sorgular-mekanizmasi-mantik-motoruna-soru-sormanin-eglenceli-yolu/"><![CDATA[<p>Bir bilgi tabanınız olduğunu düşünün: içinde gerçekler, kurallar ve biraz da dedektiflik kokan ilişkiler var. Sorgular mekanizması, bu yapıya dışarıdan soru sormamızı sağlar: Bu sonuç doğru mu, yanlış mı, yoksa sistemin bildikleriyle kanıtlanamıyor mu? Kısacası sorgu, mantık motoruna yöneltilen kontrollü bir mercek gibidir; veriyi ezberlemek yerine, sonuç çıkarmayı otomatikleştirir.
``
Sorgular özellikle mantıksal programlama, uzman sistemler, kural motorları ve bilgi grafikleri gibi alanlarda çok kullanılır. Temel fikir şudur: önce sisteme bazı gerçekler verilir, sonra bu gerçeklerden yeni bilgiler türetebilecek kurallar tanımlanır. Ardından kullanıcı, sisteme bir önerme yöneltir. Sistem de bu önermenin bilgi tabanı tarafından desteklenip desteklenmediğini araştırır.</p>

<p>Teorik olarak bir sorgu, bir mantıksal ifadenin bilgi tabanından türetilip türetilemeyeceğini sorar. Bunu şöyle yazabiliriz: $KB \models q$. Burada $KB$ bilgi tabanını, $q$ ise sorguyu temsil eder. İfade şu anlama gelir: Bilgi tabanı doğru kabul edildiğinde, sorgu da zorunlu olarak doğru mudur? Eğer sistem bunu kanıtlayabiliyorsa sonuç true, kanıtlayamıyorsa çoğu mantıksal programlama sisteminde false döner.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Anlamı</th>
      <th>Mini Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Gerçek</td>
      <td>Doğrudan bilinen bilgi</td>
      <td>parent(ayse, mehmet)</td>
    </tr>
    <tr>
      <td>Kural</td>
      <td>Yeni bilgi üretme şablonu</td>
      <td>grandparent(X, Z) :- parent(X, Y), parent(Y, Z)</td>
    </tr>
    <tr>
      <td>Sorgu</td>
      <td>Sisteme sorulan mantıksal soru</td>
      <td>grandparent(ayse, zeynep)?</td>
    </tr>
    <tr>
      <td>Çıkarım</td>
      <td>Kurallarla sonuca ulaşma süreci</td>
      <td>Ayşe, Zeynep’in büyükannesi mi?</td>
    </tr>
  </tbody>
</table>

<p>Basit bir Prolog benzeri örnek üzerinden gidelim:</p>

<div class="language-prolog highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="ss">parent</span><span class="p">(</span><span class="ss">ayse</span><span class="p">,</span> <span class="ss">mehmet</span><span class="p">).</span>
<span class="ss">parent</span><span class="p">(</span><span class="ss">mehmet</span><span class="p">,</span> <span class="ss">zeynep</span><span class="p">).</span>

<span class="ss">grandparent</span><span class="p">(</span><span class="nv">X</span><span class="p">,</span> <span class="nv">Z</span><span class="p">)</span> <span class="p">:-</span> <span class="ss">parent</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="ss">parent</span><span class="p">(</span><span class="nv">Y</span><span class="p">,</span> <span class="nv">Z</span><span class="p">).</span>

<span class="o">?-</span> <span class="ss">grandparent</span><span class="p">(</span><span class="ss">ayse</span><span class="p">,</span> <span class="ss">zeynep</span><span class="p">).</span>
</code></pre></div></div>

<p>Bu kodda ilk iki satır gerçektir. Üçüncü satır ise bir kuraldır: X, Y’nin ebeveyni ve Y de Z’nin ebeveyni ise X, Z’nin büyükanne veya büyükbabasıdır. Sorgu çalıştırıldığında sistem değişkenleri eşleştirir, yani unification yapar. $X = ayse$, $Y = mehmet$, $Z = zeynep$ değerleriyle kural sağlandığı için cevap true olur.</p>

<p>Sorgu motorunun çalışma mantığı genellikle geriye doğru zincirleme ile açıklanır. Motor, hedef sonucu kanıtlamak için şu soruyu sorar: Bu hedef hangi alt hedeflere bağlı? Sonra alt hedefleri tek tek çözmeye çalışır. Bir bakıma final sorusundan başlayıp ipuçlarını geriye doğru takip eden bir dedektif gibi davranır.</p>

<table>
  <thead>
    <tr>
      <th>Yaklaşım</th>
      <th>Nereden Başlar?</th>
      <th>Ne Zaman Kullanışlı?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Geriye doğru zincirleme</td>
      <td>Sorgudan</td>
      <td>Belirli bir sorunun cevabı aranırken</td>
    </tr>
    <tr>
      <td>İleri doğru zincirleme</td>
      <td>Gerçeklerden</td>
      <td>Tüm olası sonuçlar önceden çıkarılacaksa</td>
    </tr>
    <tr>
      <td>SQL sorgusu</td>
      <td>Tablolardan</td>
      <td>Yapısal veri filtrelenecekse</td>
    </tr>
    <tr>
      <td>Mantıksal sorgu</td>
      <td>Kurallar ve gerçeklerden</td>
      <td>İlişkisel çıkarım gerekiyorsa</td>
    </tr>
  </tbody>
</table>

<p>Buradaki önemli ayrım şudur: SQL genellikle var olan satırları filtrelerken, mantıksal sorgular var olmayan ama türetilebilen bilgileri de bulabilir. Örneğin tabloda doğrudan büyükebeveyn bilgisi bulunmayabilir; ama ebeveyn ilişkilerinden bu bilgi hesaplanabilir. Yani sorgu motoru yalnızca arama yapmaz, akıl yürütür.</p>

<p>Küçük bir Python benzeri taslakla bu fikri sezgisel olarak görebiliriz:</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">parent</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">ayse</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">mehmet</span><span class="sh">'</span><span class="p">),</span>
    <span class="p">(</span><span class="sh">'</span><span class="s">parent</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">mehmet</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">zeynep</span><span class="sh">'</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">def</span> <span class="nf">is_grandparent</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">z</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">relation</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">y</span> <span class="ow">in</span> <span class="n">facts</span><span class="p">:</span>
        <span class="k">if</span> <span class="n">relation</span> <span class="o">==</span> <span class="sh">'</span><span class="s">parent</span><span class="sh">'</span> <span class="ow">and</span> <span class="n">a</span> <span class="o">==</span> <span class="n">x</span><span class="p">:</span>
            <span class="nf">if </span><span class="p">(</span><span class="sh">'</span><span class="s">parent</span><span class="sh">'</span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> <span class="n">z</span><span class="p">)</span> <span class="ow">in</span> <span class="n">facts</span><span class="p">:</span>
                <span class="k">return</span> <span class="bp">True</span>
    <span class="k">return</span> <span class="bp">False</span>

<span class="nf">print</span><span class="p">(</span><span class="nf">is_grandparent</span><span class="p">(</span><span class="sh">'</span><span class="s">ayse</span><span class="sh">'</span><span class="p">,</span> <span class="sh">'</span><span class="s">zeynep</span><span class="sh">'</span><span class="p">))</span>
</code></pre></div></div>

<p>Bu örnek, kural motorunun yaptığı işi sadeleştirerek gösterir. Gerçekler kümesi içinde uygun ara kişi aranır. Eğer $parent(x, y)$ ve $parent(y, z)$ aynı anda sağlanıyorsa, $grandparent(x, z)$ sonucu true kabul edilir.</p>

<p>Elbette gerçek sistemlerde işler biraz daha karmaşıktır. Değişken bağlama, geri izleme, çakışan kurallar, sonsuz döngüler ve kapalı dünya varsayımı gibi konular devreye girer. Kapalı dünya varsayımı özellikle önemlidir: Sistem bir bilgiyi kanıtlayamıyorsa onu yanlış kabul eder. Bu, günlük hayattaki bilmiyorum ile aynı şey değildir. Mantıksal sistem açısından kanıt yoksa cevap çoğu zaman false olur.</p>

<p>Sonuç olarak sorgular mekanizması, kural ve gerçeklerden oluşan bir bilgi tabanını pasif bir veri yığını olmaktan çıkarır. Ona soru sorabilir, ilişkileri test edebilir ve yeni sonuçları otomatik olarak keşfedebiliriz. İyi tasarlanmış sorgular, yazılımınıza küçük ama çalışkan bir mantık asistanı eklemek gibidir: az konuşur, çok çıkarım yapar.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Bilgi" /><category term="mantıksal programlama" /><category term="sorgular" /><category term="Prolog" /><category term="kural motoru" /><summary type="html"><![CDATA[Bir bilgi tabanınız olduğunu düşünün: içinde gerçekler, kurallar ve biraz da dedektiflik kokan ilişkiler var. Sorgular mekanizması, bu yapıya dışarıdan soru sormamızı sağlar: Bu sonuç doğru mu, yanlış mı, yoksa sistemin bildikleriyle kanıtlanamıyor mu? Kısacası sorgu, mantık motoruna yöneltilen kontrollü bir mercek gibidir; veriyi ezberlemek yerine, sonuç çıkarmayı otomatikleştirir.]]></summary></entry><entry><title type="html">C++ ile Fraktal Üretimi: Kaosun Piksel Piksel Haritası</title><link href="https://sonsuzus.github.io/posts/c-ile-fraktal-uretimi-kaosun-piksel-piksel-haritasi/" rel="alternate" type="text/html" title="C++ ile Fraktal Üretimi: Kaosun Piksel Piksel Haritası" /><published>2026-07-17T00:00:00+00:00</published><updated>2026-07-17T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-ile-fraktal-uretimi-kaosun-piksel-piksel-haritasi</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-ile-fraktal-uretimi-kaosun-piksel-piksel-haritasi/"><![CDATA[<p>Fraktallar, matematiğin “az kural, çok karmaşa” diyen asi çocuklarıdır. C++ ile fraktal üretmek ise bu çocuklara bir tuval vermek gibidir: basit bir formül yazarsınız, bilgisayar milyonlarca kez tekrarlar ve ekranda sonsuz kıvrımlara benzeyen görsel bir evren belirir. Özellikle Mandelbrot kümesi, kaos teorisinin en popüler posteridir; çünkü minicik bir başlangıç farkı, bambaşka görsel sonuçlar doğurabilir.
``
Fraktal mantığının kalbinde yineleme, yani aynı işlemi tekrar tekrar uygulama fikri vardır. Mandelbrot için temel formül oldukça kısa görünür: $z_{n+1}=z_n^2+c$. Burada $z$ karmaşık bir sayıdır, $c$ ise ekrandaki her pikselin temsil ettiği noktadır. Başlangıçta $z_0=0$ alınır. Sonra bu formül belirli sayıda çalıştırılır. Eğer $|z_n| &gt; 2$ olursa noktanın “kaçtığını” söyleriz; kaçmazsa Mandelbrot kümesinin içinde veya sınırında olabilir.</p>

<p>Bu basitlik aldatıcıdır. Çünkü her piksel için aynı işlem yapılmasına rağmen sonuçlar dramatik biçimde değişir. Bir piksel 10 yinelemede kaçarken komşusu 500 yineleme boyunca dayanabilir. İşte renkleri de genellikle bu kaçış hızına göre veririz.</p>

<table>
  <thead>
    <tr>
      <th>Kavram</th>
      <th>Programdaki Karşılığı</th>
      <th>Görsel Etki</th>
      <th> </th>
      <th> </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Karmaşık sayı $c$</td>
      <td>Pikselin matematiksel koordinatı</td>
      <td>Fraktalda konum belirler</td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Yineleme sayısı</td>
      <td>Döngü limiti</td>
      <td>Detay seviyesi artar</td>
      <td> </td>
      <td> </td>
    </tr>
    <tr>
      <td>Kaçış koşulu $</td>
      <td>z</td>
      <td>&gt;2$</td>
      <td>Döngüden çıkma şartı</td>
      <td>Renk yoğunluğunu belirler</td>
    </tr>
    <tr>
      <td>Yakınlaştırma</td>
      <td>Koordinat aralığını daraltma</td>
      <td>Sonsuz detay hissi verir</td>
      <td> </td>
      <td> </td>
    </tr>
  </tbody>
</table>

<p>Aşağıdaki C++ kodu, Mandelbrot kümesini PPM formatında bir görsele yazar. PPM seçmemizin nedeni eğlenceli derecede basit olmasıdır: dosyanın başına birkaç bilgi, ardından RGB değerleri. Yani kütüphane canavarı çağırmadan piksel piksel resim üretebiliriz.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include</span> <span class="cpf">&lt;fstream&gt;</span><span class="cp">
#include</span> <span class="cpf">&lt;complex&gt;</span><span class="cp">
</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="k">const</span> <span class="kt">int</span> <span class="n">width</span> <span class="o">=</span> <span class="mi">900</span><span class="p">;</span>
    <span class="k">const</span> <span class="kt">int</span> <span class="n">height</span> <span class="o">=</span> <span class="mi">600</span><span class="p">;</span>
    <span class="k">const</span> <span class="kt">int</span> <span class="n">maxIter</span> <span class="o">=</span> <span class="mi">300</span><span class="p">;</span>

    <span class="n">std</span><span class="o">::</span><span class="n">ofstream</span> <span class="n">out</span><span class="p">(</span><span class="s">"mandelbrot.ppm"</span><span class="p">);</span>
    <span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="s">"P3</span><span class="se">\n</span><span class="s">"</span> <span class="o">&lt;&lt;</span> <span class="n">width</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">height</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">255</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="n">height</span><span class="p">;</span> <span class="o">++</span><span class="n">y</span><span class="p">)</span> <span class="p">{</span>
        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">width</span><span class="p">;</span> <span class="o">++</span><span class="n">x</span><span class="p">)</span> <span class="p">{</span>
            <span class="kt">double</span> <span class="n">real</span> <span class="o">=</span> <span class="o">-</span><span class="mf">2.5</span> <span class="o">+</span> <span class="n">x</span> <span class="o">*</span> <span class="p">(</span><span class="mf">3.5</span> <span class="o">/</span> <span class="n">width</span><span class="p">);</span>
            <span class="kt">double</span> <span class="n">imag</span> <span class="o">=</span> <span class="o">-</span><span class="mf">1.2</span> <span class="o">+</span> <span class="n">y</span> <span class="o">*</span> <span class="p">(</span><span class="mf">2.4</span> <span class="o">/</span> <span class="n">height</span><span class="p">);</span>

            <span class="n">std</span><span class="o">::</span><span class="n">complex</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span> <span class="n">c</span><span class="p">(</span><span class="n">real</span><span class="p">,</span> <span class="n">imag</span><span class="p">);</span>
            <span class="n">std</span><span class="o">::</span><span class="n">complex</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span> <span class="n">z</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>

            <span class="kt">int</span> <span class="n">iter</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="k">while</span> <span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">abs</span><span class="p">(</span><span class="n">z</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mf">2.0</span> <span class="o">&amp;&amp;</span> <span class="n">iter</span> <span class="o">&lt;</span> <span class="n">maxIter</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">z</span> <span class="o">=</span> <span class="n">z</span> <span class="o">*</span> <span class="n">z</span> <span class="o">+</span> <span class="n">c</span><span class="p">;</span>
                <span class="o">++</span><span class="n">iter</span><span class="p">;</span>
            <span class="p">}</span>

            <span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="p">(</span><span class="n">iter</span> <span class="o">*</span> <span class="mi">9</span><span class="p">)</span> <span class="o">%</span> <span class="mi">256</span><span class="p">;</span>
            <span class="kt">int</span> <span class="n">g</span> <span class="o">=</span> <span class="p">(</span><span class="n">iter</span> <span class="o">*</span> <span class="mi">5</span><span class="p">)</span> <span class="o">%</span> <span class="mi">256</span><span class="p">;</span>
            <span class="kt">int</span> <span class="n">b</span> <span class="o">=</span> <span class="p">(</span><span class="n">iter</span> <span class="o">*</span> <span class="mi">13</span><span class="p">)</span> <span class="o">%</span> <span class="mi">256</span><span class="p">;</span>

            <span class="k">if</span> <span class="p">(</span><span class="n">iter</span> <span class="o">==</span> <span class="n">maxIter</span><span class="p">)</span> <span class="p">{</span>
                <span class="n">r</span> <span class="o">=</span> <span class="n">g</span> <span class="o">=</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
            <span class="p">}</span>

            <span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="n">r</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">g</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span> <span class="o">&lt;&lt;</span> <span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="s">" "</span><span class="p">;</span>
        <span class="p">}</span>
        <span class="n">out</span> <span class="o">&lt;&lt;</span> <span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Kodda <code class="language-plaintext highlighter-rouge">real</code> ve <code class="language-plaintext highlighter-rouge">imag</code> değişkenleri, ekran koordinatını matematiksel düzleme çevirir. Yani <code class="language-plaintext highlighter-rouge">(x, y)</code> pikselini doğrudan çizmek yerine, onu karmaşık sayı düzlemindeki bir noktaya dönüştürürüz. Sonrasında <code class="language-plaintext highlighter-rouge">z = z * z + c</code> satırı fraktalın motorudur. Bu satır her piksel için yüzlerce kez çalışır; C++ burada hız avantajını gösterir.</p>

<p>Renk seçimi tamamen deney alanıdır. Yukarıdaki örnekte mod alma ile basit ama canlı bir palet oluşturduk. Daha yumuşak geçişler için logaritmik renklendirme kullanılabilir. Teorik olarak kaçış süresi $n$ ise, renk fonksiyonu $color=f(n)$ gibi düşünülebilir. Fonksiyon ne kadar yaratıcıysa fraktal o kadar “galaksi posteri” havasına bürünür.</p>

<table>
  <thead>
    <tr>
      <th>Ayar</th>
      <th>Düşük Değer</th>
      <th>Yüksek Değer</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">maxIter</code></td>
      <td>Hızlı ama az detay</td>
      <td>Yavaş ama keskin sınırlar</td>
    </tr>
    <tr>
      <td>Çözünürlük</td>
      <td>Küçük dosya</td>
      <td>Daha temiz görüntü</td>
    </tr>
    <tr>
      <td>Koordinat aralığı</td>
      <td>Geniş bakış</td>
      <td>Yakınlaştırılmış detay</td>
    </tr>
    <tr>
      <td>Renk formülü</td>
      <td>Düz görünüm</td>
      <td>Sanatsal sonuç</td>
    </tr>
  </tbody>
</table>

<p>Fraktalların büyüsü, deterministik olmalarına rağmen organik görünmeleridir. Aynı formül, aynı başlangıç, aynı sonuç; fakat sonuç, doğadaki kıyı çizgilerini, bulutları ve damar yapılarını hatırlatır. Kaos teorisi burada “rastgelelik” değil, başlangıç koşullarına aşırı duyarlılık demektir.</p>

<p>Bu programı geliştirmek için yakınlaştırma parametreleri ekleyebilir, PNG çıktısı almak için <code class="language-plaintext highlighter-rouge">stb_image_write</code> kullanabilir veya çok çekirdekli işlem için pikselleri paralel hesaplatabilirsiniz. Sonuçta C++ ile fraktal üretimi sadece görsel bir oyuncak değildir; matematik, performans ve yaratıcılığın aynı döngüde buluştuğu küçük bir evrendir.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Program" /><category term="C++" /><category term="Fraktal" /><category term="Mandelbrot" /><category term="Kaos Teorisi" /><summary type="html"><![CDATA[Fraktallar, matematiğin “az kural, çok karmaşa” diyen asi çocuklarıdır. C++ ile fraktal üretmek ise bu çocuklara bir tuval vermek gibidir: basit bir formül yazarsınız, bilgisayar milyonlarca kez tekrarlar ve ekranda sonsuz kıvrımlara benzeyen görsel bir evren belirir. Özellikle Mandelbrot kümesi, kaos teorisinin en popüler posteridir; çünkü minicik bir başlangıç farkı, bambaşka görsel sonuçlar doğurabilir.]]></summary></entry><entry><title type="html">C ile Kendi Mini Yorumlayıcını Yazmak: Sözdiziminden Bytecode’a</title><link href="https://sonsuzus.github.io/posts/c-ile-kendi-mini-yorumlayicini-yazmak-sozdiziminden-bytecodea/" rel="alternate" type="text/html" title="C ile Kendi Mini Yorumlayıcını Yazmak: Sözdiziminden Bytecode’a" /><published>2026-07-17T00:00:00+00:00</published><updated>2026-07-17T00:00:00+00:00</updated><id>https://sonsuzus.github.io/posts/c-ile-kendi-mini-yorumlayicini-yazmak-sozdiziminden-bytecodea</id><content type="html" xml:base="https://sonsuzus.github.io/posts/c-ile-kendi-mini-yorumlayicini-yazmak-sozdiziminden-bytecodea/"><![CDATA[<p>Derleyiciler bazen kara kutu gibi görünür: kodu yazarsın, bir şeyler olur ve işlemci “tamamdır” der. Oysa içeride oldukça sistemli bir mutfak çalışır. Bu yazıda C ile minicik bir dil motoru tasarlayarak <code class="language-plaintext highlighter-rouge">SET x 5</code>, <code class="language-plaintext highlighter-rouge">ADD x 3</code>, <code class="language-plaintext highlighter-rouge">PRINT x</code> gibi komutları okuyacak, sözdizimini analiz edecek ve bunları basit bir “makine dili” yani bytecode’a çevireceğiz.
``
Bir yorumlayıcının temel fikri şudur: metin hâlindeki program önce anlamlı parçalara ayrılır, sonra kurallara göre dizilir, en sonunda da çalıştırılabilir talimatlara dönüştürülür. Gerçek derleyicilerde bu süreç daha karmaşıktır; optimizasyon, tip denetimi ve hedef mimari gibi konular devreye girer. Bizim oyuncak dilimizde ise değişkenler, sayılar ve birkaç komut yeterli olacak.</p>

<p>Teorik olarak kaynak koddan çalışmaya giden yol şöyle modellenebilir:</p>

\[Kaynak\ Kod \rightarrow Tokenlar \rightarrow AST/Komutlar \rightarrow Bytecode \rightarrow VM\]

<p>Burada “VM”, sanal makine demektir. Gerçek CPU yerine kendi küçük işlemcimizi C içinde simüle ederiz. Mesela <code class="language-plaintext highlighter-rouge">ADD x 3</code> komutu, bellekteki <code class="language-plaintext highlighter-rouge">x</code> değerini alıp üzerine 3 ekleyen bir bytecode talimatına dönüşür.</p>

<table>
  <thead>
    <tr>
      <th>Aşama</th>
      <th>Görevi</th>
      <th>Örnek</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Lexer</td>
      <td>Metni parçalara ayırır</td>
      <td><code class="language-plaintext highlighter-rouge">ADD</code>, <code class="language-plaintext highlighter-rouge">x</code>, <code class="language-plaintext highlighter-rouge">3</code></td>
    </tr>
    <tr>
      <td>Parser</td>
      <td>Sıralamanın doğru olup olmadığını kontrol eder</td>
      <td><code class="language-plaintext highlighter-rouge">ADD IDENT NUMBER</code></td>
    </tr>
    <tr>
      <td>Codegen</td>
      <td>Komutu bytecode’a çevirir</td>
      <td><code class="language-plaintext highlighter-rouge">OP_ADD, var_id, 3</code></td>
    </tr>
    <tr>
      <td>VM</td>
      <td>Bytecode’u çalıştırır</td>
      <td><code class="language-plaintext highlighter-rouge">x = x + 3</code></td>
    </tr>
  </tbody>
</table>

<p>Önce komut kümemizi tanımlayalım. Bu dilde üç işlem olsun: değişkene değer atama, toplama ve ekrana yazdırma. Matematiksel olarak belleği bir fonksiyon gibi düşünebiliriz: $M(v)$, <code class="language-plaintext highlighter-rouge">v</code> değişkeninin değeridir. <code class="language-plaintext highlighter-rouge">ADD x 3</code> çalışınca yeni durum $M’(x)=M(x)+3$ olur.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">typedef</span> <span class="k">enum</span> <span class="p">{</span>
    <span class="n">OP_SET</span><span class="p">,</span>
    <span class="n">OP_ADD</span><span class="p">,</span>
    <span class="n">OP_PRINT</span><span class="p">,</span>
    <span class="n">OP_HALT</span>
<span class="p">}</span> <span class="n">OpCode</span><span class="p">;</span>

<span class="k">typedef</span> <span class="k">struct</span> <span class="p">{</span>
    <span class="n">OpCode</span> <span class="n">op</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">var</span><span class="p">;</span>
    <span class="kt">int</span> <span class="n">value</span><span class="p">;</span>
<span class="p">}</span> <span class="n">Instruction</span><span class="p">;</span>
</code></pre></div></div>

<p>Bu yapı bizim mini makine dilimizdir. <code class="language-plaintext highlighter-rouge">op</code> hangi işlemin yapılacağını söyler, <code class="language-plaintext highlighter-rouge">var</code> değişkenin kimliğini, <code class="language-plaintext highlighter-rouge">value</code> ise sayısal argümanı taşır. Gerçek makinelerde bunlar baytlara sıkıştırılır; biz okunabilir kalsın diye <code class="language-plaintext highlighter-rouge">struct</code> kullandık.</p>

<p>Şimdi basit bir değişken tablosu yazalım. Oyuncak örnekte değişkenleri tek harf kabul etmek işi çok kolaylaştırır: <code class="language-plaintext highlighter-rouge">a</code>, <code class="language-plaintext highlighter-rouge">b</code>, <code class="language-plaintext highlighter-rouge">x</code> gibi. Böylece <code class="language-plaintext highlighter-rouge">x - 'a'</code> bize 0-25 arası bir indeks verir.</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">var_id</span><span class="p">(</span><span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">name</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">if</span> <span class="p">(</span><span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;=</span> <span class="sc">'a'</span> <span class="o">&amp;&amp;</span> <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;=</span> <span class="sc">'z'</span> <span class="o">&amp;&amp;</span> <span class="n">name</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="sc">'\0'</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">name</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">-</span> <span class="sc">'a'</span><span class="p">;</span>
    <span class="k">return</span> <span class="o">-</span><span class="mi">1</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Parser tarafında satırı okuyup ilk kelimeye göre karar verebiliriz. Bu, tam teşekküllü bir parser değildir ama sözdizimi analizinin özünü gösterir: beklenen kalıba uyuyor mu?</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">int</span> <span class="nf">compile_line</span><span class="p">(</span><span class="kt">char</span> <span class="o">*</span><span class="n">line</span><span class="p">,</span> <span class="n">Instruction</span> <span class="o">*</span><span class="n">out</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">char</span> <span class="n">cmd</span><span class="p">[</span><span class="mi">16</span><span class="p">],</span> <span class="n">name</span><span class="p">[</span><span class="mi">16</span><span class="p">];</span>
    <span class="kt">int</span> <span class="n">value</span><span class="p">;</span>

    <span class="k">if</span> <span class="p">(</span><span class="n">sscanf</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s">"SET %15s %d"</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">value</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">op</span> <span class="o">=</span> <span class="n">OP_SET</span><span class="p">;</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">var</span> <span class="o">=</span> <span class="n">var_id</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span>
        <span class="k">return</span> <span class="n">out</span><span class="o">-&gt;</span><span class="n">var</span> <span class="o">&gt;=</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="n">sscanf</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s">"ADD %15s %d"</span><span class="p">,</span> <span class="n">name</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">value</span><span class="p">)</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">op</span> <span class="o">=</span> <span class="n">OP_ADD</span><span class="p">;</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">var</span> <span class="o">=</span> <span class="n">var_id</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">value</span> <span class="o">=</span> <span class="n">value</span><span class="p">;</span>
        <span class="k">return</span> <span class="n">out</span><span class="o">-&gt;</span><span class="n">var</span> <span class="o">&gt;=</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="n">sscanf</span><span class="p">(</span><span class="n">line</span><span class="p">,</span> <span class="s">"PRINT %15s"</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">op</span> <span class="o">=</span> <span class="n">OP_PRINT</span><span class="p">;</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">var</span> <span class="o">=</span> <span class="n">var_id</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
        <span class="n">out</span><span class="o">-&gt;</span><span class="n">value</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
        <span class="k">return</span> <span class="n">out</span><span class="o">-&gt;</span><span class="n">var</span> <span class="o">&gt;=</span> <span class="mi">0</span><span class="p">;</span>
    <span class="p">}</span>

    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Bu kodun eğlenceli yanı, <code class="language-plaintext highlighter-rouge">sscanf</code> ile minik bir dilbilgisi kontrolü yapmasıdır. Daha ciddi bir projede token üretir, ardından recursive descent parser yazardık. Örneğin <code class="language-plaintext highlighter-rouge">expr -&gt; term ((+|-) term)*</code> gibi kurallarla matematiksel ifadeleri ayrıştırmak mümkün olurdu.</p>

<p>Son adımda bytecode’u çalıştıran sanal makineyi yazıyoruz:</p>

<div class="language-c highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kt">void</span> <span class="nf">run</span><span class="p">(</span><span class="n">Instruction</span> <span class="o">*</span><span class="n">code</span><span class="p">,</span> <span class="kt">int</span> <span class="n">count</span><span class="p">)</span> <span class="p">{</span>
    <span class="kt">int</span> <span class="n">memory</span><span class="p">[</span><span class="mi">26</span><span class="p">]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">0</span><span class="p">};</span>

    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">ip</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">ip</span> <span class="o">&lt;</span> <span class="n">count</span><span class="p">;</span> <span class="n">ip</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
        <span class="n">Instruction</span> <span class="n">in</span> <span class="o">=</span> <span class="n">code</span><span class="p">[</span><span class="n">ip</span><span class="p">];</span>

        <span class="k">switch</span> <span class="p">(</span><span class="n">in</span><span class="p">.</span><span class="n">op</span><span class="p">)</span> <span class="p">{</span>
            <span class="k">case</span> <span class="n">OP_SET</span><span class="p">:</span>
                <span class="n">memory</span><span class="p">[</span><span class="n">in</span><span class="p">.</span><span class="n">var</span><span class="p">]</span> <span class="o">=</span> <span class="n">in</span><span class="p">.</span><span class="n">value</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="k">case</span> <span class="n">OP_ADD</span><span class="p">:</span>
                <span class="n">memory</span><span class="p">[</span><span class="n">in</span><span class="p">.</span><span class="n">var</span><span class="p">]</span> <span class="o">+=</span> <span class="n">in</span><span class="p">.</span><span class="n">value</span><span class="p">;</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="k">case</span> <span class="n">OP_PRINT</span><span class="p">:</span>
                <span class="n">printf</span><span class="p">(</span><span class="s">"%d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">memory</span><span class="p">[</span><span class="n">in</span><span class="p">.</span><span class="n">var</span><span class="p">]);</span>
                <span class="k">break</span><span class="p">;</span>
            <span class="k">case</span> <span class="n">OP_HALT</span><span class="p">:</span>
                <span class="k">return</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Buradaki <code class="language-plaintext highlighter-rouge">ip</code>, instruction pointer’dır; yani sıradaki talimatın adresini gösterir. CPU’larda da benzer bir mantık vardır. Program sayacı ilerler, talimat çözülür, işlem yapılır. Bizim VM bunu C döngüsüyle taklit eder.</p>

<p>Örnek program şöyle olabilir:</p>

<div class="language-text highlighter-rouge"><div class="highlight"><pre class="highlight"><code>SET x 10
ADD x 7
PRINT x
</code></pre></div></div>

<p>Derleme sonucunda yaklaşık olarak şu bytecode dizisi oluşur:</p>

<table>
  <thead>
    <tr>
      <th>Kaynak Satır</th>
      <th>Bytecode</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">SET x 10</code></td>
      <td><code class="language-plaintext highlighter-rouge">OP_SET, 23, 10</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">ADD x 7</code></td>
      <td><code class="language-plaintext highlighter-rouge">OP_ADD, 23, 7</code></td>
    </tr>
    <tr>
      <td><code class="language-plaintext highlighter-rouge">PRINT x</code></td>
      <td><code class="language-plaintext highlighter-rouge">OP_PRINT, 23, 0</code></td>
    </tr>
  </tbody>
</table>

<p>Çıktı doğal olarak <code class="language-plaintext highlighter-rouge">17</code> olur. Küçük ama güçlü bir fikir yakaladık: sözdizimi sadece metin kontrolü değildir; anlamlı eylemlere açılan kapıdır. Buradan sonra ifadeler, koşullar, döngüler ve hata mesajları ekleyerek mini dilinizi büyütebilirsiniz. Bir noktadan sonra fark edeceksiniz: derleyiciler büyü yapmıyor, sadece çok disiplinli bir çeviri işi gerçekleştiriyor.</p>]]></content><author><name>Sonsuz Us</name></author><category term="Proje" /><category term="C" /><category term="yorumlayıcı" /><category term="derleyici" /><category term="parser" /><category term="bytecode" /><summary type="html"><![CDATA[Derleyiciler bazen kara kutu gibi görünür: kodu yazarsın, bir şeyler olur ve işlemci “tamamdır” der. Oysa içeride oldukça sistemli bir mutfak çalışır. Bu yazıda C ile minicik bir dil motoru tasarlayarak SET x 5, ADD x 3, PRINT x gibi komutları okuyacak, sözdizimini analiz edecek ve bunları basit bir “makine dili” yani bytecode’a çevireceğiz.]]></summary></entry></feed>