İçeriğe geç
academia.sh

Ders 02 / 10

Bağlamdan Bağımsız Diller

Durum bütçesinin yetmediği dillerin ölçülmesi: eşit sayıda a ve b dizisi için gereken durum sayısı uzunluk sınırıyla 3, 5, 7, 9, 11 diye büyürken tek satırlık bir üretim kuralı aynı dili tam olarak üretiyor ve kuralın betimi hiç büyümüyor.

İçindekiler

Önceki ders bir dili düzenli sayan ölçüyü kurdu: gereken durum sayısı evren büyüdükçe büyümüyorsa o dil için sabit bir bütçe seçilebilir. İki örnek bu ölçüyü geçti; “a sayısı çift” üç evrende de 2, “ab ile biten” üç evrende de 3 durum istedi. Şimdi ölçüyü geçmeyen bir dile bakılır.

Sorulacak dil şudur: önce bir miktar a, sonra tam olarak aynı sayıda b. Bu dil bir sayma işi ister; okunan a sayısı, b’lerin sayılabilmesi için bir yerde tutulmak zorundadır. Sonlu otomatın tek belleği durumudur, ve durum sayısı sabittir. Sorunun bütün ağırlığı buradadır.

Sayma Gerektiren Bir Dil

Önceki dersin üç ölçüsü aynen kullanılır: artık dil öbeklerinin sayısı, ayrılan önek sayısı ve tam sayım. Üçü de aynı evrende çalıştırılır, sonra evren süpürülür. Yanına ikinci bir dil konur: dengeli dizi, yani a’nın açtığı ve b’nin kapattığı sayılırsa hiçbir önekte kapanışın açılışı geçmediği ve sonda eşitlendiği dizi.

  • HM10 — Hedef dil esit_sayida, yani bir dizinin ilk yarısı yalnız a, ikinci yarısı yalnız b ise ve uzunluk çiftse dile aittir. Boş dizi dile aittir.
  • HM11 — İkinci hedef dengeli, tek bir sayaçla sınanır: a sayacı bir artırır, b bir azaltır; sayaç hiçbir noktada eksiye düşmez ve sonda sıfırdır.
  • HM12 — Tam sayım bu derste k=1’den 5’e kadar yapılır. Beş durumlu geçiş tablosu sayısı 5105^{10}’dur; ölçünün bütçesi budur ve k=6 bu derste denenmedi.
  • HM13 — Ölçüm hiçbir yerde “bu dil tanınamaz” demez. Söyleyebileceği tek şey, denenen k değerleri ve denenen uzunluk sınırları içinde ne bulunduğudur.
"""a^n b^n ve dengeli dil: obek , ayrilan onek ve tam sayim yan yana."""
from itertools import product

ALFABE = ("a", "b")


def diziler(en_uzun):
    cikti = [""]
    for n in range(1, en_uzun + 1):
        cikti += ["".join(d) for d in product(ALFABE, repeat=n)]
    return cikti


def esit_sayida(d):
    """a^n b^n biciminde mi."""
    n = len(d)
    if n % 2:
        return False
    yari = n // 2
    return d[:yari] == "a" * yari and d[yari:] == "b" * yari


def dengeli(d):
    """a acar , b kapatir; hicbir onekte kapanis acilisi gecmez."""
    sayac = 0
    for s in d:
        sayac += 1 if s == "a" else -1
        if sayac < 0:
            return False
    return sayac == 0


def en_az_durum(hedef, evren):
    """Ayirt edilebilirlik obekleri: artik dillerin sayisi."""
    onekler = {d[:i] for d in evren for i in range(len(d) + 1)}
    return len({frozenset(k for k in evren if o + k in hedef) for o in onekler})


def ayrilan_onek(hedef, evren):
    """Iki onegi ancak IKI uzantisi da evrende kalan bir kuyruk ayirabilir."""
    ev = set(evren)
    onekler = sorted({d[:i] for d in evren for i in range(len(d) + 1)},
                     key=lambda o: (len(o), o))
    imza = {o: tuple((1 if o + k in hedef else 0) if o + k in ev else -1
                     for k in evren) for o in onekler}
    secilen = []
    for o in onekler:
        if all(any(x >= 0 and y >= 0 and x != y
                   for x, y in zip(imza[o], imza[p])) for p in secilen):
            secilen.append(o)
    return len(secilen)


def taniyan_var_mi(k, hedef, evren):
    """k durumlu BUTUN gecis tablolari; kabul kumesi tutarlilikla secilir."""
    hucreler = [(d, s) for d in range(k) for s in ALFABE]
    for hedefler in product(range(k), repeat=len(hucreler)):
        gecis = dict(zip(hucreler, hedefler))
        gerek, tutarli = {}, True
        for dizi in evren:
            d = 0
            for s in dizi:
                d = gecis[(d, s)]
            istenen = dizi in hedef
            if gerek.setdefault(d, istenen) != istenen:
                tutarli = False
                break
        if tutarli:
            return True
    return False


print("uzunluk   dizi   a^n b^n: obek  onek   dengeli: obek  onek")
for u in (2, 4, 6, 8, 10):
    E = diziler(u)
    h1 = frozenset(d for d in E if esit_sayida(d))
    h2 = frozenset(d for d in E if dengeli(d))
    print(f"{u:7d}  {len(E):5d}  {en_az_durum(h1, E):12d}  {ayrilan_onek(h1, E):4d}"
          f"  {en_az_durum(h2, E):14d}  {ayrilan_onek(h2, E):4d}")
print()
print("tam sayim: k = 1..5 icin BUTUN otomatlar denendi")
print("uzunluk  a^n b^n hedefi                 taniyan en kucuk k")
for u in (2, 3, 4):
    E = diziler(u)
    h = frozenset(d for d in E if esit_sayida(d))
    k = [i for i in (1, 2, 3, 4, 5) if taniyan_var_mi(i, h, E)]
    print(f"{u:7d}  {str(sorted(h)):28s}  {k[0] if k else 'yok'}")
uzunluk   dizi   a^n b^n: obek  onek   dengeli: obek  onek
      2      7             4     3               4     3
      4     31             6     5               7     4
      6    127             8     7              11     5
      8    511            10     9              16     6
     10   2047            12    11              22     7

tam sayim: k = 1..5 icin BUTUN otomatlar denendi
uzunluk  a^n b^n hedefi                 taniyan en kucuk k
      2  ['', 'ab']                    3
      3  ['', 'ab']                    3
      4  ['', 'aabb', 'ab']            5

Üç sayı yan yana. Bütçe: durum sayısı 1’den 5’e, uzunluk sınırı 2’den 10’a. Bütçenin yanıtladığı: gereken durum sayısı a’lı b’li dilde 3, 5, 7, 9, 11 diye, dengeli dilde 3, 4, 5, 6, 7 diye büyüyor; uzunluk 4 evreninde tam sayım en küçük k’yı 5 buluyor ve bu, ayrılan önek sayısıyla birebir aynı. Bütçenin yanıtlayamadığı: sabit bir k’nın hiçbir uzunlukta yetmediği. Ölçüm bunu söyleyemez; söyleyebildiği şey denenen beş uzunluk ve beş k değeri içinde durum sayısının durmadan büyüdüğüdür.

Büyümenin nedeni ölçümde değil dildedir. Önce yalnız a’dan oluşan önekler düşünülsün: iki ayrı önek olan a ile aa, b kuyruğuyla ayrılır, çünkü ab dile aittir ve aab ait değildir; üstelik iki uzantı da evrenin içindedir. Aynı şey aa ile aaa için bb kuyruğuyla, aaa ile aaaa için bbb kuyruğuyla geçerlidir. Uzunluk sınırı 2m olan bir evrende bu zincir m+1 öneğe kadar uzar ve zincirdeki her önek ayrı bir durum ister. Sınır büyüdükçe zincir uzar. Buradaki cümle kesinlikle şudur: her sabit k için, o k’nın yetmediği bir uzunluk ölçüldü; “her zaman yetmez” cümlesi kuramın sonucudur ve koşumla kurulmaz.

Tam sayım tablosunun ilk iki satırı da okunmalıdır. Uzunluk 2 ile 3 evreninde hedef aynı kalıyor, çünkü tek sayı uzunluklu hiçbir dizi dile ait değil; en küçük k ikisinde de 3. Uzunluk 4’te hedefe aabb girer girmez sayı 5’e sıçrıyor. Yani gereken durum, evrene eklenen dizi sayısıyla değil, dile yeni bir sayma derinliği eklenmesiyle artıyor. İki durumlu otomatın hafızası bir bitti; burada gereken şey, kaç a okunduğunu tutan bir sayaçtır ve sayacın alacağı değer sayısı uzunlukla birlikte artar.

Öbek sütunu ile önek sütunu arasındaki bir birimlik fark önceki dersteki üst sayımın sürdüğünü gösteriyor: a’lı b’li dilde öbek 4, 6, 8, 10, 12 iken ayrılan önek 3, 5, 7, 9, 11. İki sütunun eğimi aynı; ikisi de doğrusal büyüyor. Dengeli dilde ise iki sütun ayrışıyor, öbek 22’ye çıkarken önek 7’de kalıyor — ucuz ölçü ile sınanmış ölçü arasındaki fark, dile göre değişiyor ve bu yüzden ucuz ölçü tek başına yazılmaz.

Üretim Kuralı Otomatın Yapamadığını Yapıyor

Bütçeyi büyütmek bir yol. İkinci yol modeli değiştirmektir. Üretim kuralı (production rule), bir simgeyi bir diziyle değiştirmeye izin veren kuraldır; kuralların art arda uygulanmasına türetme (derivation) denir. Bir dilin bütün dizileri sonlu bir kural kümesinden türetilebiliyorsa o dile bağlamdan bağımsız dil (context-free language) denir.

Dilbilgisi ve ayrıştırma Bilgisayarlar Nasıl Çalışır kursundaki Derleme Aşamaları dersinde kuruldu; sözcük birimleri, soyut sözdizim ağacı ve işleç önceliğinin ağaca gömülmesi orada anlatıldı ve burada tekrarlanmaz. Bu dersin eklediği tek şey ölçüdür: kuralın ürettiği küme ile hedef dilin birebir aynı olup olmadığı.

  • HM14 — Kural S -> a S b | boş iki seçenek taşır ve tek satırdır. Türetme derinliği, kuralın kaç kez uygulandığıdır.
  • HM15 — İkinci kural S -> a S b S | boş, dengeli dizileri üretir. Ölçüm, üretilen küme ile evrendeki dengeli dizilerin kümesinin eşit olup olmadığıdır; alt küme yetmez.
  • HM16 — Kuralın betimi ile koşumu ayrı ölçülür: betim satır sayısı, koşum türetme derinliğidir.
"""Uretim kurali: betim sabit kalir , turetme derinligi girdiyle buyur."""
from itertools import product

ALFABE = ("a", "b")
KURAL = {"S": [("a", "S", "b"), ()]}          # S -> a S b | bos


def diziler(en_uzun):
    cikti = [""]
    for n in range(1, en_uzun + 1):
        cikti += ["".join(d) for d in product(ALFABE, repeat=n)]
    return cikti


def esit_sayida(d):
    n = len(d)
    if n % 2:
        return False
    yari = n // 2
    return d[:yari] == "a" * yari and d[yari:] == "b" * yari


def dengeli(d):
    sayac = 0
    for s in d:
        sayac += 1 if s == "a" else -1
        if sayac < 0:
            return False
    return sayac == 0


def turet(en_derin):
    """Kuraldan en cok `en_derin` adimda uretilen diziler."""
    uretilen = {""}
    onceki = {""}
    for _ in range(en_derin):
        yeni = {"a" + d + "b" for d in onceki}
        uretilen |= yeni
        onceki = yeni
    return uretilen


def turet_dengeli(en_uzun):
    """S -> a S b S | bos ; uzunlugu en_uzun'u gecmeyen butun turetmeler."""
    kume, degisti = {""}, True
    while degisti:
        degisti = False
        for x in list(kume):
            for y in list(kume):
                yeni = "a" + x + "b" + y
                if len(yeni) <= en_uzun and yeni not in kume:
                    kume.add(yeni)
                    degisti = True
    return kume


print("S -> a S b | bos")
print("derinlik  uretilen  en uzun  ayni uzunluktaki hedefi kapsiyor mu")
for d in (1, 2, 3, 4, 5):
    U = turet(d)
    hedef = {x for x in diziler(2 * d) if esit_sayida(x)}
    print(f"{d:8d}  {len(U):8d}  {max(len(x) for x in U):7d}  {hedef <= U}")
print("  3 adimda uretilenler:", sorted(turet(3)))
print()
print("S -> a S b S | bos")
print("uzunluk  turetilen  dengeli dizi  ikisi ayni mi")
for u in (2, 4, 6, 8):
    T = turet_dengeli(u)
    D = {x for x in diziler(u) if dengeli(x)}
    print(f"{u:7d}  {len(T):9d}  {len(D):12d}  {T == D}")
S -> a S b | bos
derinlik  uretilen  en uzun  ayni uzunluktaki hedefi kapsiyor mu
       1         2        2  True
       2         3        4  True
       3         4        6  True
       4         5        8  True
       5         6       10  True
  3 adimda uretilenler: ['', 'aaabbb', 'aabb', 'ab']

S -> a S b S | bos
uzunluk  turetilen  dengeli dizi  ikisi ayni mi
      2          2             2  True
      4          4             4  True
      6          9             9  True
      8         23            23  True

Tek satırlık kural üç türetme adımında "", ab, aabb, aaabbb üretiyor; bu, uzunluğu 6’yı geçmeyen evrendeki a’lı b’li dizilerin tamamıdır. Beş derinlikte uzunluk 10’a kadar aynı sonuç sürüyor: kapsama sütunu beş satırda da True. İkinci kural için ölçü daha sıkıdır, çünkü alt küme değil eşitlik sınanıyor: uzunluk 8’e kadar üretilen 23 dizi, evrendeki 23 dengeli dizinin aynısı.

Bu, önceki bölümün ölçtüğü şeyin karşıtıdır. Aynı dil için otomatın istediği durum sayısı 3’ten 11’e çıkarken, kuralın satır sayısı 1’de kaldı. Model sınıfını değiştirmek, bütçeyi büyütmekten başka bir şeydir: birincisi betimin boyunu sabit tutar, ikincisi betimi büyütür.

Bütçe Nereye Konuyor

İki modelin ödediği bedel aynı yerde durmuyor. Aşağıdaki tablo iki bölümün sayılarını yan yana koyar; durum sütunu ayrılan önek sayısından, derinlik sütunu türetme ölçümünden gelir.

Uzunluk sınırı Otomat: gereken durum Kural: satır Kural: türetme derinliği
2 3 1 1
4 5 1 2
6 7 1 3
8 9 1 4
10 11 1 5

Otomatta büyüyen şey betimdir: daha uzun diziler için daha büyük bir makine yazılmak zorundadır ve makinenin kendisi girdiyle birlikte büyür. Kuralda büyüyen şey koşumdur: kural aynı kalır, yalnız daha çok kez uygulanır. Bir modelin gücünü ölçerken sorulacak soru “kaç adım harcıyor” değil, “girdiyle birlikte ne büyüyor” olmalıdır.

Bu ayrımın bir bedeli de var ve saklanmaz. Kural, dizinin dile ait olup olmadığına sonlu otomatın tek geçişiyle karar vermez; türetmeyi araması gerekir, ve arama tek geçişten pahalıdır. Ölçüm bunu da gösteriyor: dengeli dil için uzunluk 8’e kadar 23 dizi üretmek, kümenin sabit noktaya oturmasına kadar yinelemeyi sürdürmeyi gerektirdi. Güç bedava gelmiyor; ödenen şey betim boyu yerine arama.

Özet

  • Eşit sayıda a ve b isteyen dilde gereken durum sayısı uzunluk sınırıyla birlikte 3, 5, 7, 9, 11 diye büyüyor; dengeli dilde 3, 4, 5, 6, 7 diye.
  • Uzunluk 4 evreninde k=1’den 5’e kadar bütün otomatlar denendi ve en küçük k 5 çıktı; bu sayı ayrılan önek ölçüsüyle birebir aynı.
  • Sabit bir k’nın hiçbir uzunlukta yetmediği ölçülmedi ve ölçülemez; ölçülen şey her denenen k için o k’nın yetmediği bir uzunluğun bulunmasıdır.
  • Tek satırlık S -> a S b | boş kuralı üç türetme adımında uzunluğu 6’yı geçmeyen bütün hedef dizileri üretiyor; S -> a S b S | boş kuralı uzunluk 8’e kadar 23 dengeli dizinin tamamını, fazlasız üretiyor.
  • Otomatta girdiyle birlikte büyüyen şey betim, üretim kuralında koşumdur; model sınıfını değiştirmek bütçeyi büyütmekten başka bir şeydir.
  • Gücün bedeli de ölçüldü: kural tek geçişte karar vermez, türetmeyi arar; kazanılan betim boyu, ödenen arama.

Sonraki Adım

İki model de bir sınırla tanımlandı: biri durum sayısıyla, öteki kural biçimiyle. Sonraki ders sınırı olabildiğince gevşetir ve okunan simgeyi değiştirebilen, ileri geri gezinebilen bir şeride sahip bir model kurar. Sorulacak soru şudur: bu modelin bütün üyelerini tek tek sayabilir miyiz, ve saydığımızda kaçının durduğunu bir adım bütçesiyle öğrenebilir miyiz. Yanıtın ilk yarısı beklenenden kolay, ikinci yarısı beklenenden zordur.

İlerlemeni kaydetmek ve not almak için Giriş yap

Notlarım

Not almak için giriş yapmalısın.

Aramak için yazmaya başlayın.

↑↓ Esc gezin · aç · kapat