- Prolog, programları tek bir clause ve term merkezli veri modeliyle kurar; böylece küçük bir söz dizimiyle bile hesaplanabilir ilişkileri ifade edebilir
- Bildirimsel yaklaşım, yürütme adımlarından ziyade neyin geçerli olduğunu yazdığı için aynı ilişki hesaplama, üretme ve sorgulama için birlikte kullanılabilir
- Saf Prolog, Horn clause ve resolution üzerine kuruludur; kısıt eklemenin ve clause eklemenin çözüm kümesine etkisi mantıksal olarak öngörülebilir
- Programın kendisi bir Prolog term’ü olduğundan başka programları okumak, analiz etmek ve dönüştürmek kolaydır; derleme zamanında yeniden yazmayla alana özgü diller de oluşturulabilir
- Çalışma zamanı dinamizmi ve arama, birleştirme, kısıt yayılımı gibi örtük mekanizmalar sayesinde dil işleme, veritabanı, doğrulama ve optimizasyona kadar geniş bir alanda kullanılır
Clause ve term’lerden oluşan küçük bir dil
- Prolog’daki tüm veriler Prolog term’leriyle ifade edilir
- Temel dil öğesi tek bir clause’tur; temel biçimi
Head :- Body. şeklindedir
- Anlamı, Body geçerliyse Head de geçerlidir demektir
- Infix operatörü
(:-)/2, sağdan sola yönelen ← okunu temsil eder
- Head her zaman geçerliyse
:- Body kısmı atlanabilir
- Yararlı bir ilk Prolog programı yazmak için yalnızca bu yapı yeterlidir
- Bilinen tüm hesaplamalar bu tür clause’larla tanımlanabildiğinden Prolog Turing complete bir dildir
- Bir Turing machine, mevcut durum ve bant kafasının altındaki sembol gibi bilgilerden sonraki duruma geçiş ilişkisini clause’larla tanımlayarak uygulanabilir
- Örnek uygulama turing.pl içinde yer alır
Bildirimsel programlama ve ilişki merkezli düşünme
- Prolog, çözümlerin nasıl bulunacağından çok, ilgilenilen çözümler hakkında neyin geçerli olduğunu ifade eden bildirimsel bir dildir
- Bu özellik kısa, açık ve genel tanımlamaları mümkün kılar
- Liste ile uzunluğu arasındaki ilişki şöyle tanımlanabilir
list_length([], 0).
list_length([_|Ls], N) :-
N #> 0,
N #= N0 + 1,
list_length(Ls, N0).
- Bazı Prolog sistemlerinde bildirimsel tamsayı aritmetiği kullanmak için ayrı bir kütüphanenin dahil edilmesi gerekir
- Bu tanım bildirimsel olarak şöyle okunabilir
- Boş liste
[]’nin uzunluğu 0’dır
Ls’nin uzunluğu N0 ise ve N, N0 + 1 ise [_|Ls]’nin uzunluğu N’dir; bu ilişki yalnızca N 0’dan büyük olduğunda geçerlidir
- Aynı ilişki birden çok modda kullanılabilir
list_length("abc", L), L = 3 döndürür
list_length(Ls, 3), uzunluğu 3 olan liste biçimini, yani Ls = [_A,_B,_C] değerini bulur
list_length(Ls, L), boş listeden başlayıp uzunluğu artan listelere kadar genel yanıtları listeler
- Prolog genellikle tüm yanıtları backtracking ile bildirir
length/2, Prologue for Prolog taslağına dahildir ve neredeyse tüm Prolog uygulamalarında aynı anlamda yerleşik bir predicate olarak sunulur
Mantıksal programlama olarak Prolog
- Bildirimsel diller kategorisinde fonksiyonel programlama dilleri ve mantıksal programlama dilleri bulunur
- Fonksiyonlar ilişkilerin özel bir durumudur; fonksiyonel programlama, mantıksal programlamanın kısıtlı bir biçimi olarak görülebilir
- Prolog’un kökleri logic’e dayanır
- Saf Prolog programları Horn clause kümelerinden oluşur
- Yürütme, resolution’ın özel bir durumu olarak görülebilir
- Biçimsel mantıkla bağlantısı sayesinde, programın mantıksal özelliklerine dayalı bildirimsel hata ayıklama uygulanabilir
- Kısıt eklendiğinde çözüm kümesi en fazla küçülür
- Clause eklendiğinde çözüm kümesi en fazla genişler
- Saf Prolog programlarının bu özelliğine monotonluk denir
- Ulrich Neumerkel’in GUPU system’i bu fikrin bir uygulama örneğidir
Programları veri gibi ele alan homoiconic özellik
- Prolog programları aynı zamanda geçerli Prolog term’leridir
- Bu özellik sayesinde Prolog programlarının başka Prolog programlarını analiz etmesi, dönüştürmesi ve yorumlaması kolaydır
- Yerleşik predicate
read/1 ile Prolog term’leri okunabilir; dolayısıyla Prolog clause’ları da okunabilir
- Prolog’da derleme zamanında programı yeniden yazan güçlü bir makro mekanizması vardır
- Bu sayede görevlerin daha doğal biçimde çözülebileceği alana özgü diller uygulanabilir
list_length(Ls,N) ile N#>0 gösterim olarak farklı görünse de Prolog’un prefix, infix ve postfix operatörleri sayesinde daha okunabilir biçimde ifade edilmişlerdir
- Örneğin Prolog term’ü
+(a,b), operatör gösterimiyle a+b olarak yazılabilir
- Soyut söz dizimi tek biçimli olduğundan, yazılış biçiminden bağımsız olarak tüm Prolog term’leri okunup işlenebilir
- Belirli kullanımlara uygun kullanıcı tanımlı operatörler dinamik olarak tanımlanabilir
Çalışma zamanı dinamizmi ve genişletilebilirlik
- Prolog programları çalışma zamanında kolayca oluşturulabilir, çağrılabilir ve değiştirilebilir
- Bu özellik ifade gücünü artırır ve başka predicate’leri argüman olarak alan higher-order predicate’lerin uygulanmasını mümkün kılar
- adaptive parsing gibi son derece dinamik teknikler de uygulanabilir
- Prolog, başka programcıların veya son kullanıcıların sağladığı kullanıcı tanımlı kurallarla genişletilen programlar yazmaya uygundur
- Saf Prolog için bir yorumlayıcı iki satır Prolog koduyla tanımlanabilir
- İlgili konu A Couple of Meta-interpreters in Prolog içinde ele alınır
Çeşitli kullanım alanları ve örtük mekanizmalar
- Prolog’un ilişkisel niteliği programları esnek ve genel hale getirir
- Bu nitelik dil işleme ve veritabanı alanlarında bilgi temsilinde önemli rol oynar
- Modern Prolog sistemleri, basit logic puzzles’dan büyük ölçekli uygulamalara kadar gerekli özellikleri sunar
- Prolog’un çok yönlülüğü ve gücü, arama, birleştirme, argüman indeksleme ve kısıt yayılımı gibi örtük mekanizmalara dayanır
- Geliştiriciler bu mekanizmalardan yararlanarak birçok işi Prolog motoruna devredebilir
1 yorum
Hacker News yorumları
Buradaki duyguya neredeyse tamamen katılıyorum. Üniversitedeki üç AI dersinde Prolog kullandım; neredeyse "AI: A Modern Approach" kitabının tamamını ve Prolog programlamayı işledik, gerçekten düşünme biçimini çarpıtan bir deneyimdi.
Prolog tarzında yeniden düşünmek için her zaman ısınmam gerekiyordu ve o dönem başka dillerde de korkunç derecede Prologvari spaghetti code yazıyordum. O zamanki en büyük dezavantaj, başka şeylerle birlikte çalışabilirliğin zor olmasıydı; ya JVM'in içine Prolog koymak, ya daha az özellikli bir implementasyon kullanmak ya da C binding'lerine bel bağlamak gerekiyordu. Belirli işler, özellikle de kısıt sağlama problemleri için harika; ama kullanıcı arayüzü ya da dosya sistemi erişimi gibi şeyler işin içine girince uygun olmadığını düşünüyordum. O dönemde SWI de gerideydi ve Sicstus gibi tescilli çözümler kullanıyorduk; yakın zamanda baktığımda SWI'ın tescilli implementasyonları yakaladığını gördüm, bugün olsa SWI'ı seçerdim. Prolog sınavı, 60 dakikalık canlı kodlamada 3 soru ve ardından sözlü sınavdan oluşuyordu; üniversitedeki en korkutucu sınavdı ama kolay soruya 40 dakika harcayıp kalan ikisini birkaç dakikada çözerek iyi atlattım. Devam dersinde, oyun oynayan ajanlar geliştirip bir turnuvada yarıştırdığımız ödev eğlenceliydi; "The Art of Prolog" ve "The Craft of Prolog" ise şimdiye kadar okuduğum programlama kitapları arasında en iyilerden.
The Craft of Prolog da mükemmel, ama eski Prolog sistem programlamasına fazla özelleştiği için bugün bazı bölümleri eskimiş durumda. Prolog'un pek çok fikri answer set programming ve Datalog'da yaşamaya devam ediyor; Datalog da modern statik analiz araçları yapmak için harika: https://arxiv.org/abs/2012.10086
Birden chatbot'ların Prolog'la nasıl başa çıkacağını merak ettim. Yeterince görmüşler midir? O şekilde akıl yürütebilirler mi?
Prolog harika ve sırf yabancı bir programlama paradigmasını deneyimlemenin keyfi için bile öğrenmeye değer. Pek çok kavram tamamen farklı bir şekilde ifade ediliyor; paradigma kafaya oturduğunda ise aksine çok daha basit hâle geliyor.
Örneğin Prolog'da genellikle koleksiyonları doğrudan manipüle etmezsiniz; koleksiyonun öğelerinin ne olduğuna dair bilgiyi verip implementasyonun bunu bulmasına izin verirsiniz. Bir bağımlılık ağacını çizmek bile üç kuralla mümkün: varlıkların ne olduğu, X ve Y varlıkları arasındaki ilişkinin nasıl belirleneceği ve bunun nasıl ifade edileceği. Ancak zor olduğu için insanları öğrenmeye ya da kullanmaya ikna etmek güç; ayrıca başka uygulamalara pürüzsüz biçimde entegre etmenin yolunu hâlâ bulamadım. FFI'ın bir seçenek olduğunu biliyorum ama production-ready olduğuna ikna olmuş değilim. Son birkaç ayda daha “production”a yakın Prolog alternatifleri aradım; fakat LispWorks ve Franz Allegro CL çok pahalıydı ve entegrasyon dostu değildi. Modern yazılımlara Prolog'u iyi entegre etmiş örnekler varsa gerçekten merak ederim. Mac'te XPCE çalışmadığı için GUI çözümü de arıyorum. Çevrimiçi notebook olarak Swish'e de bakmaya değer: https://swish.swi-prolog.org
Şu anda kaldırıldığını duydum, yani “modern” bir örnek değil; ama Prolog'un uygulanmasına gerçekten güzel bir örnek. https://news.ycombinator.com/item?id=36821871 üzerinden https://web.archive.org/web/20030218034509/http://www.resear... bağlantısına uzanıyor; okumaya fazlasıyla değer. İlgili bağlantı: https://news.ycombinator.com/item?id=14046420
İkisi de oldukça iyi çalışıyordu ama kullanım alanları sınırlıydı. Üniversitede Prolog kullanma deneyimim eğlenceliydi; fakat problem özünde Prolog biçiminde değilse kullanmak istemem. Biraz karmaşık bir şeyler implement etmeye başladığınız anda soyutlamalar birer birer sızıyor ve dilin avantajlarından yararlanmaktan çok backtracking algoritmasıyla boğuşuyormuşsunuz gibi hissettiriyor.
Racklog, Prolog tarzı mantıksal programlamayı Racket'a gömen bir sistem; buradaki “gömme” Racket'ı kaybetmediğiniz anlamına geliyor. Prolog tarzı kod parçalarını ve normal Racket kodunu yan yana kullanabilirsiniz. Meta mantık ve ikinci derece “küme” predicate'leri de dahil olmak üzere Prolog özelliklerinin çoğunu içeriyor; yalnızca Racket alt ifadeleriyle daha kolay ve verimli yapılabilen işlevleri dışarıda bırakıyor. https://docs.racket-lang.org/racklog/index.html Racket'ın GUI'si de var; hatta pratikte ihtiyaç duyacağınız neredeyse her şey de var.
CUE mevcut workflow'lara çok daha kolay dahil edilebildiği için mantıksal programlamanın avantajlarını pratik bir şeye dönüştürmekte iyi. https://cuelang.org | https://cuetorials.com
Birkaç yıl boyunca C++ ile tedarik zinciri optimizasyon yazılımı geliştirirken ILOG’un kısıt yayılımı yazılımını, yani artık IBM’in sahibi olduğu Solver’ı kullandım. O dönemde BinProlog’u da değerlendirmiştik; aralık yayılımı yerleşik geliyordu, yerel x86’ya derleniyordu ve FFI birlikte çalışabilirliği de fena değildi
Yine de sonunda SWI Prolog ve GNU araç zincirinin gerisinde kalmış gibi görünüyor. GUI’nin bambaşka bir uzmanlık alanı olarak görülmesi gerektiğini düşünüyorum; biz kendi C++ canvas rendering motorumuzu ve “4D” ya da “Fourth Dimension” adlı berbat bir entegre 4GL geliştirme aracını kullanıyorduk. https://www.tomshw.it/data/images/2/0/4/3/infor-advanced-sch...
Mark Tarver’ın Shen dilinde Prolog’un eksiksiz bir uygulaması bulunuyor: https://shenlanguage.org/SD/Prolog.html
The Book of Shen’deki ilgili bölüm de var: https://shenlanguage.org/TBoS/tbos_359.html Tarver ayrıca mantık programlama üzerine, yanında yazılım da bulunan iki kitap yazdı. Logic, Proof and Computation: https://shenlanguage.org/lpc.html Programming the Logic Lab: https://shenlanguage.org/logiclab.html
Pattern matching, isteğe bağlı tip denetimi ve yerleşik Prolog şaşırtıcı. Kurucusunun diplomatik olmayan tavrı nedeniyle daha geniş topluluktan bir ölçüde dışlandığı söylenebilir; ama kendisi çok parlak biri ve benimsenme biçimi niş ve son teknoloji çizgisinde kaldı. Arkasında Mozilla gibi bir organizasyon olsaydı çok daha geniş kitlelere çekici gelebilirdi. @deech’in sunumları artık eski olsa da hâlâ mükemmel ve anlamlı: https://www.youtube.com/watch?v=lMcRBdSdO_U, https://www.youtube.com/watch?v=BUJNyHAeAc8 Yalnız ben bir APL/J/BQN fanatiğiyim; bunu dikkate alarak dinleyin
Yaklaşık 25 yıl önce yapay zeka + bilgisayar bilimi lisans programında Prolog öğrendiğimi hatırlıyorum. Doğal dil işleme modülünde epey kullanmıştık
Başta bunaltıcı ve sinir bozucuydu ama alışınca şaşırtıcı derecede eğlenceli hâle geldi; yineleme yapmak için özyineleme dışında yol olmadığından özyinelemeye giriş için de harikaydı
Üniversitede Prolog’u çoğunlukla zaten bu tür dilleri kullanan matematikçilerden öğrendik ve onlar için Prolog çok doğal bir düşünme biçimiydi. Buna karşılık ağırlıklı olarak prosedürel diller kullanmış öğrenciler için kafa karıştırıcı ve bunaltıcıydı; herkes Prolog’u başka bir dil gibi kullanmaya çalışıp tökezliyordu. Prolog kullandığımız üçüncü ya da dördüncü derste, arkasındaki algoritmaları çalıştıktan sonra ancak nasıl iyi kullanılacağı kafama oturdu. Daha sonra Prolog yüzünden zorlanan bir lisans öğrencisine yardım ettim; kilit nokta Prolog’u alıştığı diller gibi hareket ettirmeye çalışmak değil, problem çözme düşüncesini Prolog dünyasına uyacak şekilde değiştirmekti. Epey uzun konuştuktan sonra gerçek bir aydınlanma anı yaşadı ve ödevini mükemmel şekilde bitirdi
Ama yeni paradigma zihnimde tam yerine oturduktan sonra gerçekten sevmeye başladım. O aydınlanma anı bile tek başına o dersi almaya değerdi
Diğer yorumlar Prolog’u genel olarak tartışıyor ama The Power of Prolog’un oldukça iyi bir eğitim serisi olduğunu söylemek isterim
Videoları da izlemeye değer; Markus izleyicinin ve okurun ilgisini iyi canlı tutuyor
Bu video sayesinde Prolog’u programlamada hâlâ devam eden ve ilerici bir hareket olarak görmeye başladım
Prolog güzel bir dil. Matematiksel akıl yürütme, kural tabanlı çıkarım vb. için on binlerce satır yazdım; bu alanlara kusursuz uyuyor ve onunla çalışmak inanılmaz eğlenceli
Diğer tür uygulamalarda iki sorun var. Birincisi, paradigma çok farklı olduğu için kütüphaneler ve diğer dillerle pek iyi uyuşmuyor. İkincisi, düzgün bir GUI yapmak neredeyse imkânsız; çünkü bu da paradigmaya uymuyor
Genelde Prolog tarafında dış arayüz, tüm argümanları temel hâle getirilmiş bir yüklem gibi görünür; dış tarafta ise Prolog’la SQL veritabanıyla çalışır gibi etkileşirsiniz. Sorgu gönderir, sorguyu parçalara ayırır, daha fazla çözüm ister ya da backtracking’i çalıştırırsınız. Bu tür bir etkileşimin “ilginç” olmadığı söylenebilir; ama kütüphaneler Prolog’un faydalı özelliklerinden fiilen yararlanmadığı için böyle işler. İsterseniz daha kalın bir birlikte çalışabilirlik katmanı kurabilir, birden fazla kütüphane fonksiyonunu Prolog tarafında tek bir yüklem arayüzünde toplayıp argümanların örneklenme moduna göre belirli bir alt rutini çağırmasını sağlayabilirsiniz. Ama bu, bir C kütüphanesini Python gibi nesne yönelimli bir dile açarken birden fazla C fonksiyonunu özellik eriştiricileri ya da bir veri yapısının metotları gibi gruplayıp sunmaktan pek farklı değildir
Veri analizinde Prolog’u aktif olarak kullanıyorum. Başta, soruları sembolik problemlere dönüştürmeyi anlamak için mümkün olan her şeyi Prolog’la yapmaya kendimi zorladığım bir aşamadan geçmem gerekti
Prolog’un bilimsel hesaplama ve string işleme desteği berbat olduğu için. O aşamayı geçince Prolog çözümleri çoğu zaman bir sonraki en iyi alternatiften daha zarif oluyor. Ayrıca mantık paradigması olduğu için olumsuzlama yoluyla ispat + birleştirme = mantıksal programlamaya dönüşen süreci anlamaya zaman ayırmaya değer. Öğrendiğim programlama dilleri içinde ufkumu açık ara en çok genişleten dil oldu
Standart Prolog’da regex yerleşik gelmiyor, ama popüler implementasyonlar genellikle bunun için kütüphane sağlıyor. Çok fazla string işi yapmam gerekse ve C ile Prolog arasında seçim yapacak olsam kesinlikle Prolog’u seçerdim. Python ile Prolog arasında ise işe göre değişir
Her hâlükârda harika bir site ve bu konunun yeniden gündeme gelmesine sevindim
Daha önce Java ile bir çözücü yazmıştım, o kodu Prolog’a taşımaya çalıştım ama hiç işlemedi. Sonunda baştan başladım ve Sudoku’nun geçerli olup olmadığını kontrol eden basit Prolog kodu yazdım; sonra o yüklemleri çalıştırınca Sudoku’yu da çözebildiğini fark ettim. Böylece çözücüyü 10 satırdan kısa sürede tamamladım. Gerçek bir eureka anıydı; Prolog çok güçlü ama pratikte haksız derecede az kullanılıyor. Neyse ki Datalog ve OWL ile çalışma fırsatım oldu