İçeriğe geç
academia.sh

Ders 05 / 22

Öz Eleştiri ve Doğrulama

Ajanın durduktan sonra kendi izine bakmasının kattığı ve katladığı: üç gözlenebilir işaret yirmi dört kurgu görevde okunduğunda tur, dar bütçelerde yanlış yanıtların hepsini bayrağa takıyor ama sekiz adımda temiz izli bir yanlış yanıtı hiç göremiyor. Dört adım bütçesinde başarım 21/24'ten 23/24'e çıkıyor, karşılığında adım 84'ten 152'ye ve belirteç 9402'den 17052'ye. Aynı adımlar tek bir uzun koşuma verildiğinde sekiz adım bütçesi 97 adım ve 11978 belirteçle aynı 23/24'ü veriyor. Altı adımda tur başarımı 24/24'ten 23/24'e düşürüyor; sekiz adımda hiç değiştirmiyor ve yedi bayrağın altısı gereksiz yeniden koşum. İki koşum farkı bir görevdir, bu yüzden altı ve sekiz adımdaki fark ölçülmemiş sayılır.

İçindekiler

Önceki dört derste döngü kuruldu ve nerede duracağı yazıldı. Ajan bir araç seçiyor, dönen gözlemi durumuna yazıyor, sonraki adımı ona bakarak atıyor; işi bittiğinde ya da bütçe dolduğunda duruyor. Kapandığı anda elde bir yanıt kalıyor.

Dört ders boyunca bir kez sorulmayan şey şu: o yanıt doğru mu. Ajan durduğunda kendi izine dönüp bakmıyor. Bu ders o eksik turu ekler ve iki şeyi ölçer: turun yakaladığını ve turun ödettiğini. Aynı istemi birkaç kez koşturup yanıtları oylamak bundan ayrı bir düzenektir ve İstem Mühendisliği kursunda ölçüldü; burada oylanacak birden çok yanıt yok, tek bir döngünün bıraktığı ize bakılıyor.

  • AM41. Kurulum ortaktır: ölçüm ağının kurgu abone kayıtları, kurgu belge dağarcığı, beş kurgu araç, yirmi dört kurgu görev ve ders içinde yazılmış bir ajan benzeticisi. Gerçek bir model ucu ya da araç sunucusu çağrılmaz.
  • AM42. Taban çizgisi düzeneksiz döngüdür: aynı küme, aynı bütçe, tur kapalı. Bütçenin iki katına çıkarılmış tursuz satır da tabloda durur, çünkü turun harcadığı adım tek bir uzun koşuma da verilebilirdi.
  • AM43. Tur doğru yanıtı göremez; yalnız üç gözlenebilir işarete bakar: döngü kendi mi durdu, araç hatası düştü mü, bir yanıt üretildi mi.
  • AM44. Üçünden biri bozuksa görev kuşkulu sayılır ve döngü ikinci kez koşar. Tur bir kezdir ve yanıtı düzeltebildiği gibi bozabilir de.
  • AM45. Turun bedeli her koşumdan sonra bir adım ve 45 + 18 x len(iz) belirteçtir; turlu koşumda her araç hatası izin okunması için 40 belirteç ekler.
  • AM46. İkinci koşum tohum 20260219; bu kümede iki koşum farkı bir görevdir (0,0417) ve altındaki her fark ölçülmemiş sayılır.

Turun Bakabildiği Üç İşaret

Turun elinde doğru yanıt yoktur; olsaydı ajana gerek kalmazdı. Elinde yalnız iz vardır.

# ORTAK KURGU KURULUM -- olcum aginin 60 kurgu abonesi, 5 kurgu belge,
# 5 kurgu arac, 24 kurgu gorev ve ders icinde yazilmis ajan benzeticisi.
# Gercek bir model ucu, arac sunucusu ya da calisma zamani cagrilmaz.
TOHUM, M32 = 20260218, 0xFFFFFFFF


def uretec(t):
    x = ((t ^ (t >> 16)) * 2246822507) & M32
    x = ((x ^ (x >> 13)) * 3266489909) & M32
    s = [(x ^ (x >> 16)) & M32]

    def sonraki():
        s[0] = (s[0] * 1664525 + 1013904223) & M32
        return s[0] / 4294967296
    return sonraki


def ayrik(u, w):
    t = 0.0
    for i, x in enumerate(w):
        t += x
        if u < t:
            return i
    return len(w) - 1


def belirtecle(m):
    b = []
    for s in str(m).lower().replace(",", " , ").split():
        while len(s) > 5:
            b.append(s[:5])
            s = s[5:]
        b.append(s)
    return b


def izno(m):
    h = 2166136261
    for c in str(m):
        h = ((h ^ ord(c)) * 16777619) & M32
    return h


# ---- KURGU ortam: olcum aginin kayitlari
BOLGE = ["dogu", "bati", "kuzey", "guney", "merkez"]
TIP = ["mesken", "isyeri"]
ABONE = {}
for i in range(60):
    r = uretec(TOHUM + 31 * i)
    onceki = 10000 + int(r() * 80000)
    ABONE[f"A{i + 1:03d}"] = {"bolge": BOLGE[int(r() * 5)], "tip": TIP[int(r() * 2)],
                              "onceki": onceki, "simdiki": onceki + int(r() * 70)}
BASAMAK, USTU = ((10, 4), (25, 7), (40, 11)), 16
ISYERI_KAT = 2
BELGE = {"TR01": "tarife basamaklari 10 25 40 metrekup ve ustu",
         "TR02": "isyeri abonesinde birim ucret iki katidir",
         "SY01": "endeks farki tuketimi verir sayac donusu 100000 eklenir",
         "AR01": "ariza kaydi acildiginda saha ekibi iki gun icinde gider",
         "KS01": "planli kesinti duyurusu bir hafta once yayimlanir"}

CAGRI = [0]                              # arac cagri sayaci


def _bedel(m3, tip):
    kalan, alt, top = m3, 0, 0
    for ust, birim in BASAMAK:
        dilim = min(kalan, ust - alt)
        if dilim <= 0:
            break
        top += dilim * birim
        kalan -= dilim
        alt = ust
    top += kalan * USTU
    return top * (ISYERI_KAT if tip == "isyeri" else 1)


def t_sayac_oku(abone=None, **_):
    a = ABONE.get(abone)
    if a is None:
        return {"hata": "abone yok"}
    return {"onceki": a["onceki"], "simdiki": a["simdiki"], "tip": a["tip"], "bolge": a["bolge"]}


def t_tuketim(onceki=None, simdiki=None, **_):
    if onceki is None or simdiki is None:
        return {"hata": "eksik alan"}
    f = simdiki - onceki
    return {"m3": f + 100000 if f < 0 else f}


def t_tarife(m3=None, tip="mesken", **_):
    if m3 is None:
        return {"hata": "eksik alan"}
    return {"tutar": _bedel(m3, tip)}


def t_belge(anahtar=None, **_):
    if not anahtar:
        return {"hata": "eksik alan"}
    ab = set(belirtecle(anahtar))
    en, kod = -1, None
    for k, m in BELGE.items():
        o = len(ab & set(belirtecle(m)))
        if o > en:
            en, kod = o, k
    return {"kod": kod, "metin": BELGE[kod]} if en > 0 else {"hata": "bulunamadi"}


def t_kayit(abone=None, sutun=None, deger=None, **_):
    if not (abone and sutun and deger is not None):
        return {"hata": "eksik alan"}
    return {"yazildi": True, "abone": abone, "sutun": sutun, "deger": deger}


ARAC = {
    "sayac_oku":  {"islev": t_sayac_oku, "alan": ("abone",), "yan_etki": False},
    "tuketim":    {"islev": t_tuketim, "alan": ("onceki", "simdiki"), "yan_etki": False},
    "tarife":     {"islev": t_tarife, "alan": ("m3", "tip"), "yan_etki": False},
    "belge_ara":  {"islev": t_belge, "alan": ("anahtar",), "yan_etki": False},
    "kayit_yaz":  {"islev": t_kayit, "alan": ("abone", "sutun", "deger"), "yan_etki": True},
}
ARAC_ADI = list(ARAC)


def cagir_arac(ad, durum):
    """Sema disindaki alanlar suzulur; eksik alan aracin kendi hatasidir."""
    CAGRI[0] += 1
    if ad not in ARAC:
        return {"hata": "arac yok"}
    kw = {a: durum[a] for a in ARAC[ad]["alan"] if a in durum}
    return ARAC[ad]["islev"](**kw)


# ---- KURGU gorevler: her biri bilinen bir arac dizisiyle cozulur
GOREV = []
for i in range(24):
    r = uretec(TOHUM + 9973 * i)
    ab = f"A{1 + int(r() * 60):03d}"
    t = ayrik(r(), [0.30, 0.22, 0.20, 0.28])
    if t == 0:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "bedel", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem bedeli nedir",
                      "dizi": ("sayac_oku", "tuketim", "tarife")})
    elif t == 1:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "tuketim", "abone": ab,
                      "istek": f"{ab} abonesinin bu donem tuketimi kac metrekup",
                      "dizi": ("sayac_oku", "tuketim")})
    elif t == 2:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "belge", "abone": ab,
                      "istek": "sayac donusunde endeks farki nasil hesaplanir",
                      "dizi": ("belge_ara",)})
    else:
        GOREV.append({"ad": f"G{i + 1:02d}", "tur": "kayit", "abone": ab,
                      "istek": f"{ab} abonesinin bedelini hesapla ve kayda yaz",
                      "dizi": ("sayac_oku", "tuketim", "tarife", "kayit_yaz")})


def dogru_yanit(g):
    a = ABONE[g["abone"]]
    f = a["simdiki"] - a["onceki"]
    m3 = f + 100000 if f < 0 else f
    if g["tur"] == "tuketim":
        return m3
    if g["tur"] == "belge":
        return "SY01"
    return _bedel(m3, a["tip"])


# ---- KURGU ajan: her adimda bir arac secer ya da biter
def gorme(d):
    return max(0.34, 0.80 - 0.09 * (d - 1))       # dogru araci secme payi, derinlikle duser


def ajan(g, en_cok_adim=8, tohum=TOHUM, oz_elestiri=False, onay=False):
    """KURGU ajan dongusu. Gercek bir model cagrilmaz; arac secimi
    gorevin dizisine ve derinlige bagli tek bir cekilisten gelir."""
    r = uretec(tohum ^ izno(g["ad"]))
    alan = {"abone": g["abone"], "anahtar": g["istek"], "sutun": "bedel"}
    iz, adim, bel, hata = [], 0, 0, 0
    dizi, k = g["dizi"], 0
    while adim < en_cok_adim:
        adim += 1
        bel += 60 + 22 * len(iz)
        hedef = dizi[k] if k < len(dizi) else None
        if hedef is None:                          # is bitti , ajan durmali
            if r() < 0.88:
                return {"bitti": True, "adim": adim, "iz": iz, "belirtec": bel,
                        "hata": hata, "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}
            sec = ARAC_ADI[int(r() * len(ARAC_ADI))]
        else:
            sec = hedef if r() < gorme(k + 1) else ARAC_ADI[int(r() * len(ARAC_ADI))]
        if ARAC[sec]["yan_etki"] and onay:
            alan["onay"] = alan.get("onay", 0) + 1
        if sec == "kayit_yaz":
            alan["deger"] = alan.get("sonuc")
        s = cagir_arac(sec, alan)
        iz.append((sec, "hata" in s))
        bel += 30
        if "hata" in s:
            hata += 1
            if oz_elestiri:
                bel += 40
            continue
        alan.update({kk: vv for kk, vv in s.items() if kk != "hata"})
        if sec == "tuketim":
            alan["sonuc"] = s["m3"]
        if sec == "tarife":
            alan["sonuc"] = s["tutar"]
        if sec == "belge_ara":
            alan["sonuc"] = s["kod"]
        if sec == hedef:
            k += 1
    return {"bitti": False, "adim": adim, "iz": iz, "belirtec": bel, "hata": hata,
            "yanit": alan.get("sonuc"), "onay": alan.get("onay", 0)}



# ---- Bu derste eklenen parca: oz elestiri turu


def kuskulu(s):
    """Turun bakabildigi uc isaret: dongu kendi mi durdu, arac hatasi
    dustu mu, bir yanit uretildi mi. Dogru yanit turun elinde yoktur."""
    return (not s["bitti"]) or s["hata"] > 0 or s["yanit"] is None


def denetim_bedeli(s):
    return 45 + 18 * len(s["iz"])


print("gorev  tur      bitti  hata  yanit  kuskulu  dogru")
for g in GOREV[:6]:
    s = ajan(g, en_cok_adim=2)
    print(f"{g['ad']:<7}{g['tur']:<9}{str(s['bitti']):<7}{s['hata']:<6}"
          f"{str(s['yanit'] is not None):<7}{str(kuskulu(s)):<9}"
          f"{s['yanit'] == dogru_yanit(g)}")


def dort_hucre(b, tohum):
    c = {"ky": 0, "kd": 0, "sy": 0, "sd": 0}
    for g in GOREV:
        s = ajan(g, en_cok_adim=b, tohum=tohum)
        c[("k" if kuskulu(s) else "s")
          + ("d" if s["yanit"] == dogru_yanit(g) else "y")] += 1
    return c


print("\nbutce     tohum  kuskulu+yanlis  kuskulu+dogru  sessiz+yanlis  sessiz+dogru")
for b in (2, 4, 8):
    for t in (TOHUM, TOHUM + 1):
        c = dort_hucre(b, t)
        print(f"{b:>5}{t:>10}{c['ky']:>14}{c['kd']:>15}{c['sy']:>15}{c['sd']:>14}")

print("\nsessiz kalan yanlis yanit (butce 8, tohum 20260219):")
for g in GOREV:
    s = ajan(g, en_cok_adim=8, tohum=TOHUM + 1)
    if not kuskulu(s) and s["yanit"] != dogru_yanit(g):
        print(" ", g["ad"], g["tur"], [a for a, h in s["iz"]])
        print("  yanit", s["yanit"], "-- dogrusu", dogru_yanit(g))
gorev  tur      bitti  hata  yanit  kuskulu  dogru
G01    belge    False  2     False  True     False
G02    belge    True   0     True   False    True
G03    tuketim  False  1     False  True     False
G04    tuketim  False  0     True   True     True
G05    bedel    False  0     True   True     False
G06    bedel    False  0     True   True     False

butce     tohum  kuskulu+yanlis  kuskulu+dogru  sessiz+yanlis  sessiz+dogru
    2  20260218            15              6              0             3
    2  20260219            14              7              0             3
    4  20260218             3              7              0            14
    4  20260219             4              6              0            14
    8  20260218             1              6              0            17
    8  20260219             0              6              1            17

sessiz kalan yanlis yanit (butce 8, tohum 20260219):
  G15 kayit ['sayac_oku', 'tuketim', 'tarife', 'tuketim', 'kayit_yaz']
  yanit 57 -- dogrusu 582

İlk tablo turun niçin ucuz olmadığını gösteriyor. Dar bütçede altı görevin beşi bayrağa takılıyor; dördü gerçekten yanlış, biri (G04) doğru yanıt üretmiş. İşaret bozukluğu yanlışlığın kanıtı değil, bakma nedenidir.

Dört hücrelik tablo bunu bütün kümede doğruluyor. Dar bütçelerde sessiz kalan yanlış yanıt yoktur; bedel gereksiz bayraklardır, dört adımda üç yanlışa karşılık yedi tane. Sekiz adımda tablo tersine dönüyor ve bloğun son satırları sessiz kalan görevi basıyor. G15 bir kayıt görevidir; dizisi tamamlanmış, döngü kendi durmuş, araç hatası düşmemiştir. Ama ajan işi bittikten sonra dolaşıp tuketim aracını yeniden çağırmış, bu çağrı biriken sonucu tutar yerine tüketimle ezmiş ve o değer kayda yazılmıştır. İz temiz görünüyor çünkü her adım tek başına geçerlidir; bozuk olan adımların sırasıdır.

Turun Kattığı ve Katladığı

Tur şimdi bir düzenek olarak koşturulur.

def kosum(b, tohum, tur=False):
    """tur=False duz dongudur. tur=True: dongu biter, tur ize bakar,
    kuskuluysa ayni gorev ikinci bir dongude bir kez daha kosar."""
    CAGRI[0] = 0
    d = {"dogru": 0, "adim": 0, "bel": 0, "bayrak": 0, "kurtaran": 0, "bozan": 0}
    for g in GOREV:
        s = ajan(g, en_cok_adim=b, tohum=tohum, oz_elestiri=tur)
        d["adim"] += s["adim"] + tur
        d["bel"] += s["belirtec"] + (denetim_bedeli(s) if tur else 0)
        ilk = s["yanit"] == dogru_yanit(g)
        if tur and kuskulu(s):
            d["bayrak"] += 1
            s = ajan(g, en_cok_adim=b, tohum=tohum ^ izno("tur2|" + g["ad"]),
                     oz_elestiri=True)
            d["adim"] += s["adim"] + 1
            d["bel"] += s["belirtec"] + denetim_bedeli(s)
        son = s["yanit"] == dogru_yanit(g)
        d["dogru"] += son
        d["kurtaran"] += son and not ilk
        d["bozan"] += ilk and not son
    d["cagri"] = CAGRI[0]
    return d


for t in (TOHUM, TOHUM + 1):
    print(f"\ntohum {t}")
    print("duzen            basarim   adim  cagri  belirtec  bayrak kurtaran bozan")
    for b in (2, 4, 6, 8):
        for ad, tur in (("tursuz", False), ("turlu ", True)):
            d = kosum(b, t, tur)
            ek = (f"{d['bayrak']:>8}{d['kurtaran']:>9}{d['bozan']:>6}" if tur
                  else f"{'-':>8}{'-':>9}{'-':>6}")
            print(f"butce {b:>2}, {ad}{d['dogru']:>6}/24{d['adim']:>7}"
                  f"{d['cagri']:>7}{d['bel']:>10}{ek}")
tohum 20260218
duzen            basarim   adim  cagri  belirtec  bayrak kurtaran bozan
butce  2, tursuz     9/24     48     45      4758       -        -     -
butce  2, turlu     13/24    135     84     13007      21        4     0
butce  4, tursuz    21/24     84     64      9402       -        -     -
butce  4, turlu     23/24    152     94     17052      10        2     0
butce  6, tursuz    24/24     92     71     10884       -        -     -
butce  6, turlu     23/24    164    102     19671       9        0     1
butce  8, tursuz    23/24     97     74     11978       -        -     -
butce  8, turlu     23/24    155     94     18821       7        1     1

tohum 20260219
duzen            basarim   adim  cagri  belirtec  bayrak kurtaran bozan
butce  2, tursuz    10/24     48     45      4758       -        -     -
butce  2, turlu     12/24    135     83     12839      21        4     2
butce  4, tursuz    20/24     83     67      9366       -        -     -
butce  4, turlu     22/24    151     96     16822      10        2     0
butce  6, tursuz    23/24     96     74     11610       -        -     -
butce  6, turlu     23/24    155     96     18493       7        0     0
butce  8, tursuz    23/24     98     74     11994       -        -     -
butce  8, turlu     23/24    152     92     18312       6        0     0

Dört adımlık bütçe turun en iyi göründüğü satırdır: başarım 21/24’ten 23/24‘e, iki koşumda da iki görev. Bedel: adım 84’ten 152‘ye, çağrı 64’ten 94’e, belirteç 9402’den 17052’ye. On bayrağın yalnız ikisi bir yanıtı düzeltiyor.

Sekiz adımlık tursuz satır bu kazancı bağlamına oturtuyor: 23/24, 97 adım, 11978 belirteç. Turun 152 adımla ulaştığı yere düz döngü 97 adımda varıyor; fazlalık daha uzun bir tek koşuma verildiğinde aynı başarım daha ucuza alınıyor. İki adımlık bütçede fark daha serttir: turlu koşum 135 adımla 13/24 verirken, dört adımlık düz koşum 84 adımda 21/24 veriyor.

Altı adımlık satır kursun ikinci iddiasının açık örneğidir: düz döngü orada 24/24 yapıyor, tur eklendiğinde 23/24’e iniyor. Dokuz bayrağın hiçbiri bir yanlışı düzeltmiyor, biri doğru bir yanıtı bozuyor.

Bandın Altında Kalan

Bu tablodaki her fark bir bulgu değildir. Düz döngünün başarımı iki tohumda altı adımda 24/24 ve 23/24, sekizde 23/24 ve 23/24; ölçüm bandı bir görevdir. Turun altı adımda ödettiği bir görevlik düşüş ve sekizdeki sıfır fark bu bandın içindedir ve ölçülmemiş sayılır: mekanizma gösterilebilir, etkisi bu küme büyüklüğünde ölçülemez. Bandın üstünde kalan tek kazanç dört adımlık bütçedir. Sekiz adımda turun tek somut sayısı bedeldir: yedi bayrak, altısı gereksiz ve sıfır kazanılmış görev.

Özet

  • Duran bir ajan kendi izine bakabilir ama doğru yanıtı göremez; bakabildiği üç işarettir: kendi durup durmadığı, araç hatası düşüp düşmediği, bir yanıt üretip üretmediği.
  • İşaret bozukluğu yanlışlığın kanıtı değildir: dört adımlık bütçede on bayrağın yalnız üçü yanlış bir yanıta karşılık gelir.
  • Geniş bütçelerde temiz izli bir yanlış yanıt çıkar; kendi durmuş ve hatasız bir döngü, dolaşırken biriken sonucu ezebilir ve tur bunu göremez.
  • Turun en yüksek kazancı dört adımlık bütçede iki görevdir (21/24 → 23/24); adım 84’ten 152’ye, belirteç 9402’den 17052’ye çıkar. Aynı 23/24’ü sekiz adımlık düz döngü 97 adımda veriyor.
  • Altı ve sekiz adımdaki farklar iki koşum bandının (bir görev) içindedir ve bulgu sayılmaz.

Sonraki Adım

Bu derste denetleyen ile denetlenen aynı döngüydü ve tur, izin yüzeyiyle sınırlı kaldı. Bakan gözü döngünün dışına çıkarmanın bir yolu işi bölüp ikinci bir ajana vermektir. Sonraki ders aynı görev kümesinde tek ajan ile iki ajanı yan yana koyar. Ölçülecek olan yalnız başarım değildir; devredilen bağlamın belirteci ve devirde kaybolan alan sayısı ayrıca sayılır, çünkü ikinci bir ajanın bedeli adımla değil iletişimle ödenir.

İ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