// fiko.zeka.* Lua bağlama katmanı — Geometri Zekâ Motoru (graf + GPE pipeline). // Mimari kural: her sistem doğuştan makro + plugin + olay erişilebilir. // Motor uygulamada kurulur → `zekaAyarla` ile bağlanır; bağlı değilse tüm // fonksiyonlar nil + Türkçe hata metni döner (Lua konvansiyonu: sonuc, hata). #include "fiko/betik/makro_motor.hpp" #include #include #include "fiko/sahne/sahne.hpp" #include "fiko/zeka/pipeline.hpp" #include "fiko/zeka/zeka_motoru.hpp" extern "C" { #include "lauxlib.h" #include "lua.h" } namespace fiko::betik { namespace { int hataDon(lua_State* L, const std::string& mesaj) { lua_pushnil(L); lua_pushlstring(L, mesaj.data(), mesaj.size()); return 2; } // Gövde varlığı çöz: kimlik 0 = ilk seçili gövde. Başarıda brep'li Dugum döner. Dugum* govdeSec(Sahne& sahne, u32& kimlik, std::string& hata) { if (kimlik == 0) { const std::vector sec = sahne.seciliGovdeler(); if (sec.empty()) { hata = "Gövde verilmedi ve seçili gövde yok"; return nullptr; } kimlik = sec[0]; } Dugum* d = sahne.bul(kimlik); if (!d || !d->brep) { hata = "Gövde bulunamadı ya da BREP içermiyor: " + std::to_string(kimlik); return nullptr; } return d; } // Çözülmemiş ya da bayat gövdeyi çözer; günceli olduğu gibi kullanır. 0 = hata. u64 cozGerekirse(zeka::ZekaMotoru& z, Sahne& sahne, u32& kimlik, std::string& hata) { Dugum* d = govdeSec(sahne, kimlik, hata); if (!d) return 0; const u64 kok = z.govdeKok(kimlik); if (kok != 0 && !z.bayatMi(kimlik)) return kok; return z.govdeCoz(*d->brep, kimlik); } void jsonKacir(std::string& hedef, const std::string& m) { for (unsigned char c : m) { if (c == '"' || c == '\\') { hedef += '\\'; hedef += (char)c; } else if (c < 0x20) { hedef += "\\u00"; hedef += "0123456789abcdef"[c >> 4]; hedef += "0123456789abcdef"[c & 15]; } else hedef += (char)c; } } } // namespace // fiko.zeka.coz([govde][, noktalarDahil]) → kök düğüm kimliği. govde yoksa seçili. int MakroMotor::l_zekaCoz(lua_State* L) { MakroMotor* m = kendisi(L); if (!m->zeka_) return hataDon(L, "Zekâ motoru bağlı değil"); u32 kimlik = static_cast(luaL_optinteger(L, 1, 0)); const bool noktalar = lua_toboolean(L, 2) != 0; std::string hata; Dugum* d = govdeSec(m->sahne_, kimlik, hata); if (!d) return hataDon(L, hata); const u64 kok = m->zeka_->govdeCoz(*d->brep, kimlik, nullptr, noktalar); if (kok == 0) return hataDon(L, "Gövde çözülemedi: " + std::to_string(kimlik)); lua_pushinteger(L, static_cast(kok)); return 1; } // fiko.zeka.pipeline(jsonPlan[, govde]) → sonuç JSON metni. govde verilirse // (0 = seçili) önce çözülür; verilmezse mevcut graf üzerinde koşar. int MakroMotor::l_zekaPipeline(lua_State* L) { MakroMotor* m = kendisi(L); if (!m->zeka_) return hataDon(L, "Zekâ motoru bağlı değil"); const char* json = luaL_checkstring(L, 1); if (!lua_isnoneornil(L, 2)) { u32 kimlik = static_cast(luaL_optinteger(L, 2, 0)); std::string hata; if (cozGerekirse(*m->zeka_, m->sahne_, kimlik, hata) == 0) return hataDon(L, hata.empty() ? "Gövde çözülemedi" : hata); } zeka::Pipeline p = zeka::Pipeline::jsonDanKur(json); if (!p.hata().empty()) return hataDon(L, "Pipeline planı bozuk: " + p.hata()); const zeka::PipelineSonuc s = p.calistir(m->zeka_->graf); if (!s.basarili()) return hataDon(L, s.hata); const std::string metin = s.jsonYaz(); lua_pushlstring(L, metin.data(), metin.size()); return 1; } // fiko.zeka.dugum(kimlik) → düğüm JSON metni (özellikler + ilişkiler). int MakroMotor::l_zekaDugum(lua_State* L) { MakroMotor* m = kendisi(L); if (!m->zeka_) return hataDon(L, "Zekâ motoru bağlı değil"); const u64 kimlik = static_cast(luaL_checkinteger(L, 1)); const std::string metin = m->zeka_->graf.dugumJson(kimlik); if (metin.empty()) return hataDon(L, "Düğüm yok: " + std::to_string(kimlik)); lua_pushlstring(L, metin.data(), metin.size()); return 1; } // fiko.zeka.ozet([govde]) → gövdenin düğüm tip sayıları JSON'u (gerekirse çözer). int MakroMotor::l_zekaOzet(lua_State* L) { MakroMotor* m = kendisi(L); if (!m->zeka_) return hataDon(L, "Zekâ motoru bağlı değil"); u32 kimlik = static_cast(luaL_optinteger(L, 1, 0)); std::string hata; const u64 kok = cozGerekirse(*m->zeka_, m->sahne_, kimlik, hata); if (kok == 0) return hataDon(L, hata.empty() ? "Gövde çözülemedi" : hata); const zeka::GrafDeposu& g = m->zeka_->graf; std::map sayilar; // kararlı sıra (aynı gövde → aynı çıktı) int toplam = 0; for (u64 dk : g.govdeDugumleri(kimlik)) { const zeka::ZDugum* d = g.dugum(dk); if (!d || d->silik) continue; ++sayilar[g.adMetin(d->tip)]; ++toplam; } // Feature düğümleri BREP-bağsız — govdeDugumleri'nde YOKLAR (özet 0 çıkıyordu). for (u64 dk : m->zeka_->govdeFeatureleri(kimlik)) { const zeka::ZDugum* d = g.dugum(dk); if (!d || d->silik) continue; ++sayilar[g.adMetin(d->tip)]; ++toplam; } std::string j = "{\"govde\":" + std::to_string(kimlik) + ",\"kok\":" + std::to_string(kok) + ",\"dugumSayisi\":" + std::to_string(toplam) + ",\"tipler\":{"; bool ilk = true; for (const auto& [ad, n] : sayilar) { if (!ilk) j += ','; ilk = false; j += '"'; jsonKacir(j, ad); j += "\":" + std::to_string(n); } j += "}}"; lua_pushlstring(L, j.data(), j.size()); return 1; } } // namespace fiko::betik