İÇİNDEKİLER

Ebat: px
Şu sayfadan göstermeyi başlat:

Download "http://alikoker.name.tr İÇİNDEKİLER"

Transkript

1 i İÇİNDEKİLER TEġEKKÜR... Hata! Yer işareti tanımlanmamış. ĠÇĠNDEKĠLER... i ÖZET... vii ABSTRACT... ix 1.GĠRĠġ PROLOG UN (PROGRAMMING IN LOGIC) TEMELLERĠ Gerçekler: Bilinen olgular Kurallar: Verilen Gerçeklerden Hüküm Çıkarma Sorgulamalar: (Querries) Gerçekler, Kurallar ve Sorgulamaların Bir Araya Yazılması DeğiĢkenler: Genel Cümleler Bölüm Özeti KonuĢma Dilindeki Cümlelerin Prolog Programlarına Aktarılması Cümleler (Gerçekler ve Kurallar) Olgular Arasındaki ĠliĢkiler: Yüklemler (Predicates) DeğiĢkenler (Genel Cümleler) Prolog da DeğiĢkenlerin Değer Alması Anonim DeğiĢkenler Hedefler (Sorgular) Açıklama Satırları EĢleĢtirme Bölüm özeti VISUAL PROLOG PROGRAMLARININ TEMEL BÖLÜMLERĠ Clauses(Olgular veya Kurallar) Predicates (Yüklemler) Domains (DeğiĢken Tipleri) Goal (Hedef) Yüklem Tanımı Domains (Tip tanımları) Bölümü... 22

2 ii 3.7. Goal Bölümü Deklarasyon ve Kurallara Ayrıntılı BakıĢ Char Real String Symbol Yüklemlerdeki Argümanların Yazılması Kuralların Yazım Biçimi Prolog ve Diğer Dillerdeki if Komutunun KarĢılaĢtırılması Otomatik Tip DönüĢtürmeler Bir Programın Diğer Bölümleri Database Bölümü Constants Bölümü Global Bölümü Derleyici Direktifleri Include Direktifi Bölüm Özeti EġLEġTĠRME VE GERĠYE ĠZ SÜRME Geriye Ġz Sürme Geriye Ġz Sürme Mekanizmasının Ayrıntıları Geriye Ġz Sürmenin 4 Temel Prensibi Tarama ĠĢleminin Kontrol Edilmesi fail Yükleminin Kullanılması Geriye Ġz Sürmeyi Engelleme Cut Komutunun Kullanımı Geriye Ġz Sürmeyi Engelleme Determinism ve Cut Not Yüklemi Prosedürel Açıdan Prolog Kurallar ve Olguların Prosedürlere Benzerliği Bir Kuralın Case ifadesi Gibi Kullanılması... 55

3 iii Bir Kural Ġçinde Test Yapmak Cut Komutunun Goto Gibi Kullanılması HesaplanmıĢ Değerleri Görüntüleme BASĠT VE BĠLEġĠK NESNELER Basit veri nesneleri Veri Nesneleri Olan DeğiĢkenler Veri Nesneleri Olan Sabitler Karakterler Sayılar Atomlar BileĢik Veri Nesneleri ve Fonksiyon Operatörleri BileĢik Nesnelerin EĢleĢtirilmesi BileĢik Nesneleri EĢleĢtirmek Ġçin = Sembolünün Kullanılması Birden Fazla Nesneyi Tek Nesne Olarak Kullanmak BileĢik Nesnelerin Tiplerini Tanımlamak Tip Tanımlamaları Üzerine Kısa Bir Özet Çoklu-Düzey BileĢik Nesneler Çoklu-Tipli Argümanlar Listeler TEKRARLAMA VE REKÜRSĠYON Tekrarlı ĠĢlemler Geriye Ġz Sürme Önceki ve Sonraki Eylemler Döngülü Geriye DönüĢün Uygulanması Rekursif Prosedürler Rekursiyonun Avantajları Sondan Rekursiyon Optimizasyonu Sondan Rekursiyonun Kullanımı Sondan Rekursiyonu Engelleme Rekursiyonda Cut Kullanımı Argümanların Döngü DeğiĢkeni Olarak Kullanımı... 85

4 iv 6.8. Rekursiv Veri Yapıları Ağaç Biçimindeki Veri Türleri Bir Ağaç Yapısında Tarama Yapma Bir Ağaç OluĢturmak Binary Arama Ağacı Ağaca Bağlı Sıralama LĠSTELER VE REKÜRSĠYON Listeler Liste Tanımlanması Bir Listenin Parçaları: BaĢ ve Kuyruk Listelerin ĠĢlenmesi Listelerin Kullanılması Liste Elemanlarının Sayılması Sondan Rekursiyona Yeniden BakıĢ Liste Elemanlığı Listeleri BirleĢtirme Rekursiyona Prosedürel Bir BakıĢ Bütün Çözümleri Bir Defada Bulma BileĢik Listeler AKIġ DENETĠMĠ BileĢik AkıĢ Yüklemlerin AkıĢ Biçimlerini Tanımlama AkıĢ Analizini Kontrol Etmek Referans DeğiĢkenler Referans Tip Tanımı Referens Tip ve Ġzleme Dizileri(array) Referans Tip Kullanımı AkıĢ Biçimine Yeni Bir BakıĢ Ġkili (Binary) Ağaç Yapısının Referans Tip Ġle Kullanımı Referans Tip Kullanarak Sıralama Binary (Ġkili) Tip

5 v Binary Terimlerin Kullanılması Binary Terimlerin Yazım Biçimi Binary Terimlerin OluĢturulması makebinary(1) composebinary(2) getbinarysize(1) Binary Terimlere EriĢim getentry(2) setentry(3) Binary Terimleri EĢleĢtirme Binary Terimleri KarĢılaĢtırma Terimleri Binary Terimlere DönüĢtürme term_bin(3) Hatalar ve Ġstisnalarla UğraĢma exit(0), exit(1) trap(3) errormsg(4) Hataların Bildirilmesi Hata Düzeyi lasterror(4) Terim Okuyucudan Gelen Hataları Görme consulterror(3) readtermerror(2) Break Kontrolü (Sadece Metin Modunda) break(1) breakpressed(1) DOS Metin Modunda Kritik Hata Kontrolü criticalerror(4) fileerror(2) Dinamik Cut Programlama Stilleri

6 vi Cut Yüklemini YerleĢtirmek ÖZEL GELĠġTĠRĠLMĠġ PROLOG ÖRNEKLERĠ Küçük bir Uzman Sistem örneği Basit bir yön problemi Hazine Avcısı TARTIġMA VE SONUÇ KAYNAKLAR ġekġller ve TABLOLAR ÖZGEÇMĠġ... Hata! Yer işareti tanımlanmamış.

7 vii ÖZET Yüksek Lisans Tezi PROLOG PROGRAMLAMA DĠLĠ ĠLE MAKĠNE MÜHENDĠSLĠĞĠ ALANINDA UZMAN SĠSTEMLERĠN HAZIRLANMASI TEKNĠKLERĠ Yavuz Selim AYDIN Harran Üniversitesi Fen Bilimleri Enstitüsü Makina Anabilim Dalı 1998, Sayfa: 164 Günümüzde bilgisayar alanında gözlenen hızlı değiģim, yeni teknolojik imkanların ortaya çıkmasına neden olmaktadır. Ġnsanoğlu daha bundan birkaç yıl öncesinde hayal edemediği geliģmelerin günümüzde gerçekleģtiğini gördükçe hayretler içerisinde kalmaktadır. Bilgi teknolojiyle yakından ilgilenenler dahi, bu hızlı değiģime ayak uydurmada zorlanabilmektedir. Bilgisayarların insanlar gibi düģünmesine sağlamak için yoğun çalıģmalar sürdürülmededir. Mümkün olduğunca insan beyni fonksiyonlarına yakın iģlevleri yerine getirebilecek mikroiģlemcilerin tasarımı üzerinde çalıģmalar sürdürülmektedir. Bu çalıģmalar beģinci kuģak bilgisayar dönemine rastladığı ve bu kuģak içerisinde Yapay Zeka (Artificial Intelligece) alanlarında önemli geliģmelerin yer aldığı görülür. Bilgi teknolojisinin amacı, uzman kiģilerin bilgilerini bilgisayarda kullanarak yeni sonuçlar elde etmektir. Uzman sistemler, yapay zekanın bir dalı olup, bir probleme uzman insan düzeyinde bir çözüm bulmak için uzman bilgisini kullanırlar. Yapay zekada sık kullanılan programlama dillerinden biri de Prolog dilidir. Son versiyonu Visual Prolog olarak piyasaya çıkartılmıģtır. Visual Prolog, ifadeler mantığının kullanarak, bilgisayara çözümü aranan problem hakkında bilinen gerçekleri ve kuralları vererek, uygun bir çözüm elde edilmesine sağlar.

8 viii Konvansiyonel programlama dillerinde, bir programcı herhangi bir problemin nasıl çözüleceğini bilgisayara adım adım tanıtmak zorundadır. Oysa bir Visual Prolog programcısının yapması gereken Ģey, çözüm aranan problem hakkında bilinen gerçekler ve kuralları, bunlar arasındaki iliģkileri tanımlamak, daha sonra mümkün olana bütün çözümleri bulmak görevini Prolog a vermektir. Visual Prolog, aritmetik iģlemlerin yapılmasına da imkan tanır. Visual Prolog, C++ ve diğer bilinen programlama dilleri kadar hızlı çalıģır. Hızlı bir derleyici, bilgisayar dünyasında daima aranan bir avantaj olmuģtur. Visual Prolog, MS DOS, Windows 3.1, Windows 95, Windows NT, Unix ve OS/2 iģletim sistemleri altında programlamaya imkan tanıyan bir çoklu ortam programlama dilidir. Uzman sistemlerin, bütün kullanıcılara düģük maliyetli uzmanlık, insanlar için tehlikeli olan ortamlarda riski azaltma, emekli olabilen veya vefat edebilen insan uzmanlar yerine, her zaman kalıcı olan uzmanlar ve verilen kararların net açıklanabilmesi gibi güzel özellikleri vardır. Bu çalıģma, yapay zeka alanında çalıģma yapan, uzman sistem tasarlamak isteyen fakat Türkçe kaynak bulamayan, kaynak kullanarak Prolog dilini öğrenmek isteyen araģtırmacılara faydalı olmak amacıyla gerçekleģtirilmiģtir. Prologun temel mantığı, elemanların ayrıntılı anlatımı, Prologun en önemli özelliklerinden biri olan Geriye Ġz Sürme ve bu konuların açık biçimde kullanıldığı örnekler doyurucu bilgi sunmaktadır. Anahtar Kelimeler: Uzman Sistemler, Yapay Zeka, Visual Prolog, Programlama Dilleri

9 ix ABSTRACT Master Thesis TECHNQUES ON THE DESIGN OF EXPERT SYSTEMS IN MECHANICAL ENGINEERING BY USING THE VISUAL PROLOG PROGRAMMING LANGUAGE Yavuz Selim AYDIN Harran University Graduate School of Natural and Applied Sciences Department of Mechanical Engneering 1998, Page: 164 Rapid advancement in the computer technology has brought new technological facilities. People are surprised to see that the technological innovations which could not even be dreamt of just a few years ago have been achieved. Even those closely involved in the Information Technology may sometimes face some difficulties in coping up with the rapid changes. Intensive studies have been performed by scientists to enable a computer to imitate human beings in the way he thinks. Studies to design microprocessors capable of performing similar functions of human brain still continue. It is observed that such studies coincided with the evolution period of the fifth generation computers and that important improvements have been recorded in the field of Artificial Intelligence. Information technology aims at making use of an expert s knowledge from which new results may be retrieved. Being a subbranch of Artificial Intelligence, expert systems use the knowledge of a human expert to find a solution for a given problem at expert level. One of the programming languages frequently used in artificial intelligence is Prolog, of which the latest version has been released as the Visual Prolog. It uses

10 x logical expressions which tell the computer the facts and rules about a problem so that a solution based on the given facts and rules could be obtained by using a deductive procedure. In conventional programming languages, a programmer must describe the solution to a problem step by step. In the Visual Prolog, on the other hand, a programmer must only describe the facts and rules about a problem not steps necessary for the solution- in the form of some relations and then, let the Visual Prolog find all possible solutions for that problem. Visual Prolog is capable of performing arithmetic operations as well. Visual Prolog runs as fast as C++ and other popular programming languages. A fast compiler has always been an advantage in the computing world. The Visual Prolog is a multiplatform programming language that allows programming under MS DOS, Windows and NT, Unix and OS/2 operating systems. Experts systems have some interesting characteristics such as low cost of expertise for all users, low risks in situations dangerous for humans, ever continuing expertise despite to human experts who may retire or pass away, and clear explanation of what has been concluded. This study has been performed for researchers who wish to carry out studies in the field of Artificial Intelligence, design expert systems in Mechanical Engineering but lack to find a source about the Visual Prolog in Turkish and like to learn this language. Many superior features of the Visual Prolog, including backtracking and recursion, have been clearly explained in this study by providing many sample programs. Keywords: Expert Systems, Artificial Intelligence, Visual Prolog, Programming Languages

11 1. GİRİŞ Ġngilizce Expert System kelimelerinden türetilerek Türkçe ye kazandırılmıģ olan Uzman Sistem yazılımları alanında, ülkemizde yoğun çalıģmaların yapıldığı gözlenmektedir. Bir Uzman Sistem, Bilgisayar Destekli Eğitim amaçlı da kullanılabileceğine göre, eğitim ve öğretim için gerekli olabilecek her türlü formasyonu taģımalıdır. Öğrenme, doğrudan bilgisayardan yapılacağı için, klasik öğretmen merkezli eğitime nazaran, içeriğin daha doyurucu ve cazip özellikler taģıması gerekir. Cazip unsurlar, bilgisayar tarafından yönetilmeli ve uygun ortamlarda ekranda veya bilgisayarın çevre birimlerinde ortaya çıkabilmelidir. Öğretilmek istenen bir konuda iģlem basamaklarının sırası çok önemlidir. Öğrenciye yöneltilecek sorular çok iyi belirlenmeli ve soru sorarken öğretme mekanizması devreye alınmalıdır. Soruların sıralanıģında yeterli hassasiyet gösterilmediği takdirde, hem öğrenme eksik olabilir, hem de öğrenci yanlıģ bilgilendirmeye sevk edilebilir. Uzman sistem üzerinde çalıģan öğrenci, bilgisayarı ile yalnız baģına kalacaktır. Sürekli monoton bir ekran görüntüsü yüzünden, öğrencinin öğrenme arzusu kırılabilir, bilgisayar önünde canı sıkılabilir. O halde öğretme esnasında, öğrencinin dikkatinin konuya sevk edilebilmesi için, program arasında görsel ve iģitsel yöntemlerle uygun uyarılar yapılabilmelidir. Bilgisayar destekli eğitimin kullanılabileceği her yere ilave olarak, problemlere çözüm getirilmek istenen her sahada Uzman Sistem kullanılabilir. Bir Uzman Sistem hazırlanırken asgari olarak aģağıdaki hususların göz önünde bulundurulması gerekir. Hazırlanacak proje konusu hem güncel olmalı hem de o konuda yeterli kaynak bulunabilmelidir. Konunun bol miktarda resim ve Ģekil içermesi, kullanıcının öğrenme hızını artıracak bir faktördür. 1

12 Proje baģlangıcında, güzel bir sunu yazılımıyla (örneğin Power Point gibi) proje hakkında özet bilgiler verilmeli, proje tasarımcısı ve denetleyen kiģilerin isimleri, resimleri ve faydalanılan kaynaklar hakkında bilgi verilmelidir. Konu anlatımına geçmeden önce, güzel bir müzik eģliğinde bilgisayar, kullanıcının ismini girmesini istenmelidir. Çünkü ilerleyen konular içerisinde bazı yerlerde esprili cümlelerle bilgisayarın kullanıcıya ismi ile hitap etmesi, kullanıcının aniden dikkatini çekmeye neden olabilmekte ve kullanıcı bu durumdan fazlasıyla memnun kalabilmektedir. 2

13 2. PROLOG UN (PROGRAMMING IN LOGIC) TEMELLERİ Bir Prolog programı, (Basic, Fortran, Pascal, C) olduğu gibi bir dizi komut satırından değil, doğruluğu önceden bilinen gerçeklerden ve bu gerçeklerden bilgi sağlamaya yarayan kurallardan oluģur. Prolog, cümlecikler (Horn Clauses) üzerine bina edilmiģtir. Cümlecikler, yüklem mantığı denilen formal sistemin bir alt kümesidir. Prolog da bir Karar Motoru (Inference Engine) vardır. Bu motor, verilen bilgiyi kullanarak cevabı aranan bir problem için, mantıksal bir Ģekilde karar veren bir iģlemdir. Karar motorundaki Kalıp EĢleĢtirici (Pattern Matcher) sorulara uygun olan cevapları eģleģtirerek önceden bilinen ve program içine kaydedilen bilgiyi geri çağırır. Prolog, program satırları içinde sorulan bir soruyu veya hipotezi doğrulamak için, doğruluğu önceden bilinen ve veri olarak yüklenmiģ olan bilgi kümesini sorgulayıp hipotezin doğruluğu hakkında karar vermeye çalıģır. Kısaca söylemek gerekirse, bir Prolog programının temelini, program akıģı içinde önceden verilen gerçekler ve kurallar oluģturur. Prolog un önemli diğer bir özelliği de Ģudur: Sorulan sorulara mantıklı cevaplar bulmanın yanısıra, bulduğu tek bir çözümle yetinmez, baģka alternatifleri de inceleyerek mümkün olan bütün çözümleri bulur. Prolog, bir programın birinci satırından baģlayıp sonuncu satırına kadar ilerleyip sadece bir çözüm bulmak yerine, zaman zaman geriye dönüģ yaparak problemin her bir bölümünün çözümü için alternatif yolları da arar. Yüklem mantığı, mantığa dayalı fikirleri yazılı bir Ģekilde ifade etmeye yarayacak Ģekilde geliģtirilmiģtir ve Prolog da bu mekanizma gayet iyi kullanılır. Yüklem mantığının yaptığı ilk iģ, cümlelerdeki gereksiz kelimeleri ayıklamaktır. Daha sonra cümleler-kelimeler arasındaki iliģkiler ilk sıraya, nesneler ise iliģkilerden sonra sıralanır. Bu nesneler ise iliģkilerin etkili olduğu argümanlar olarak yazılır. Konuşma Dili Prolog daki Karşılığı Ahmet bir insandır. insan(ahmet). Gül kırmızıdır. kirmizi(gul). Ahmet, gülü kırmızı ise sever. sever(ahmet, gul) if kirmizi(gul). 3

14 Prolog ile program yazarken, ilk önce nesneler ve bu nesneler arasındaki iliģkiler tanımlanır. Ahmet gülleri sever cümlesindeki Ahmet ve gül kelimeleri nesne, sevmek ise bu iki nesne arasındaki iliģkidir. Bu iliģkinin ne zaman doğru olacağını belirleyen ifadeye ise Kural denir. Ahmet, gülü kırmızı ise sever cümlesindeki sevmek hangi durumda Ahmet in gülü seveceğini belirttiği için bu durumda Kural olur Gerçekler: Bilinen olgular Prolog da, nesneler arasındaki iliģkiye Yüklem denir. Tabii dilde bir iliģki bir cümle ile sembolize edilir. Prolog un kullandığı yüklem mantığında ise bir iliģki, bu iliģkinin ismi ve bunu takiben parantez içinde yazılan nesne veya nesnelerden oluģan basit ifadelerle özetlenir. Gerçekler, tıpkı cümlelerdeki gibi. ile biter. AĢağıdaki örneklerde sevmek fiilinin tabii dilde ifade edilmesi gösterilmiģtir. Yasin Esra yı sever. Esra Cihat ı sever. Yasin kedileri sever. Yukarıdaki ifadeleri olgu olarak kabul edip Prolog daki karģılıklarını yazalım: sever(yasin, esra). sever(esra, cihat). sever(yasin, kediler). Görüldüğü gibi, gerçekler nesnelerin ve iliģkilerin değiģik özelliklerini de ifade edebilirler Kurallar: Verilen Gerçeklerden Hüküm Çıkarma Kurallar, gerçek olguları kullanarak bir sonuca varmak için kullanılır. AĢağıda sevmek iliģkisinden elde edilen bazı kurallar verilmiģtir: Yasin, Esra nın sevdiği her Ģeyi sever. Hasan kırmızı olan her Ģeyi sever. Bu kuralları Prolog dilinde yazmak gerekirse: sever(yasin, hersey):-sever(esra, hersey). sever(hasan, hersey):- kirmizi(hersey). 4

15 Buradaki :- sembolü, prosedürel dillerdeki if(eğer) anlamında olup, bir kuralın iki parçasını birleģtirir. Prolog, sever(yasin, hersey):-sever(esra, hersey) kuralını kullanarak, Yasin in sevdiği nesneyi bulmak için önce kuralın ikinci kısmını, yani Esra nın sevdiği nesneyi bulur. Bunun doğruluğu ispatlandıktan sonra Yasin in sevdiği nesneyi belirler Sorgulamalar: (Querries) Prolog a bazı gerçekler tanıtıldıktan sonra, artık bu gerçeklerle ilgili sorular sormaya baģlanabilir. Bunu Prolog Sistemini Sorgulama diyoruz. Veri olarak saklanan gerçekler ve gerçekler arasındaki iliģkiler bilindikten sonra, bu iliģkiler hakkında soru sorup cevap almak kolaydır. Günlük konuģmalarda Esra Yasin i seviyor mu? Ģeklindeki bir soruyu Prolog da Ģöyle ifade edilir. sever(esra, yasin). Bunun cevabı program akıģı içerisinde verdiğimiz gerçeklere bağlıdır. Yasin neyi sever? Ģeklindeki bir soruyu Prolog a sormamız mümkündür. Bunu sever(yasin, Neyi) Ģeklinde kodlarsak, Prolog dan Ģu cevabı alırız: Neyi=esra Neyi=kediler 2 Solutions Çünkü önceden verilen sever(yasin, esra) ve sever(yasin, kediler) iliģkileri, bunu ispatlamaktadır. Burada Yasin ve Esra'ın küçük harfle, Neyi kelimesinin ise büyük harfle baģlamaktadır. Çünkü, yüklemdeki Yasin sabit bir nesnedir, yani değeri sabittir. Oysa Neyi bir değiģkendir. Yani farklı gerçeklerle beraber, sorgudan alınacak cevaplar da farklı olacaktır. Bu yüzden değiģkenler daima büyük harf veya bir _ ile baģlar. Bu durumda Neyi kelimesinin cevapları değiģebilir. Prolog bir sorguya cevap ararken daima önceden verilen gerçeklerin ilkinden baģlar ve hiçbirini ihmal etmeden en sondaki gerçeğe kadar ilerler. Prolog da, bir insana sorulabilecek baģka soruları da sormak mümkündür. Fakat Mehmet hangi kızı sever? Ģeklindeki bir soruya hiçbir cevap alınamaz. Çünkü 5

16 yukarıdaki satırlar dikkate alındığında, bu konuyla ilgili bir bilginin mevcut olmadığı görülür. Yasin Esra yı sevmektedir, fakat Esra nın kız olduğuna dair bir bilgi mevcut olmadığından, Prologun bu gerçeklerden hareketle bir karara varması mümkün olamaz Gerçekler, Kurallar ve Sorgulamaların Bir Araya Yazılması 1. AĢağıdaki gerçekler ve kuralların var olduğunu kabul edilsin. Büyük araba hızlıdır. Büyük bir araba iyidir. Küçük bir araba daha kullanıģlıdır. Kasım, eğer hızlı ise, büyük arabayı ister. Yukarıdaki gerçeklerden anlaģılan Ģey, Kasım ın hızlı ve büyük arabalardan hoģlandığıdır. Prolog da aynı sonuca varacaktır. Zaten hızlı arabalar hakkında bilgi verilmeseydi, hiçkimse Kasım ın hızlı arabalardan hoģlandığı sonucuna varamazdı. Yapılabilecek tek Ģey, ne tür bir arabanın hızlı olacağını tahmin etmektir. 2. AĢağıdaki örneğe bakarak, Prolog un kuralları kullanarak sorgulara nasıl cevap bulduğu açıklanmıģtır. hoslanir(cengiz, masa_tenisi). hoslanir(mehmet, yuzme). hoslanir(yavuz, futbol). hoslanir(levent, Spor):-hoslanir(yavuz, Spor). Son satırdaki hoslanir(levent, Spor):-hoslanir(yavuz, Spor) bir kural olup, konuģma dilindeki karģılığı Ģudur: Levent, bir spor türünden eğer Yavuz da hoģlanıyorsa hoģlanır. Bu kuralın baģ tarafı hoslanir(levent, Spor) ve gövde kısmı hoslanir(yavuz, Spor) olur. Burada Levent in yüzmeyi sevip sevmediği hakkında hiçbir bilgi yoktur. Bunu öğrenmek için hoslanir(levent,yuzme) Ģeklinde bir sorgu kullanmak yeterlidir. Cevap bulmak için Prolog hoslanir(levent, Spor):-hoslanir(yavuz, Spor) kuralını kullanır. Yukarıda geçen gerçeklerle bunlar arasındaki iliģkiler, aģağıdaki Ģekilde bir program haline getirilir PREDICATES 6

17 nondeterm hoslanir(symbol,symbol) CLAUSES hoslanir(cengiz, masa_tenisi). hoslanir(mehmet, yuzme). hoslanir(yavuz, futbol). hoslanir(levent, Spor):- hoslanir(yavuz, Spor). GOAL hoslanir(levent, futbol). Bu program Prolog da derlenirse, yes cevabını alınır. Çünkü hoslanir(yavuz, futbol) gerçeği Yavuz un futboldan hoģlandığını göstermektedir. hoslanir(levent, Spor):-hoslanir(yavuz, Spor) kuralı ise Levent in, Yavuz un yaptığı spor türlerinden hoģlandığını göstermektedir. Ġlgili olgu Yavuz un futboldan hoģlandığını gösterdiği için, Levent in de futboldan hoģlandığını söylemek mümkündür. Bu yüzden GOAL hoslanir(levent, futbol) sorgusunun cevabı yes olur. Fakat hoslanir(levent, tenis) sorgusunun cevabı no olacaktır. Çünkü: 1. Bu sorgunun doğrulanabilmesi için gerçekler arasında öncelikle Yavuz un tenisten hoģlandığını gösteren bir olgunun var olması gerekir. 2. hoslanir(levent,spor):-hoslanir(yavuz, Spor) kuralı, üstteki gerçekleri kullanarak bu konuda bir karara varamaz. Çünkü kuralın gövdesini doğrulayacak bir bilgi olmadığından, kural baģarısız olur Değişkenler: Genel Cümleler Prolog da değiģkenler kullanılarak genel gerçekler, kurallar yazılabilir ve genel sorular sorulabilir. DeğiĢkenler tabii dilde de kullanılır. Tipik bir örnek vermek gerekirse: Kasım, Ferit in sevdiği Ģeyi sever. Bu bölümün baģında da belirtildiği gibi, Prolog da değiģkenler daima büyük harf veya bir _ ile baģlar. sever(kasim, Sey):-sever(ferit, Sey) Ģeklinde ifade edilebilecek yukarıdaki cümlede, Sey değiģkendir. kasim ve ferit kelimeleri sabit semboller oldukları için küçük harfle baģlarlar. Bu sabitleri de ekrana büyük harfle baģlayacak Ģekilde yazmak mümkündür. Bunun için sadece ( Kasim, Sey) veya ( Ferit, Sey) Ģeklinde yazmak yeterlidir. 7

18 2.6. Bölüm Özeti 1. Bir Prolog programı iki tür ifadelerden oluģur: Gerçekler ve Kurallar. Gerçekler, programcının doğruluğundan emin olduğu bilgiyi iliģkiler veya özellikler olarak anlattığı satırlardır. Kurallar, bağımlı iliģkilerdir. Prolog bu kuralları kullanarak bir bilgiden hareketle bir konuda karar verir. Bir kural, verilen Ģartlar yerine geliyorsa baģarılı olur, yani doğru olur. Prolog da bütün kuralların iki kısmı vardır: BaĢ ve Gövde kısmı. Bunlar birbirinden :- sembolleri ile ayrılırlar. BaĢ kısmı verilen gerçekler doğrulanıyorsa doğrudur. Bu kısım aynı zamanda sonuç veya bağımlı iliģki olarak da bilinir. Gövde kısmı ise doğru olması gereken Ģartları taģır. Böylece Prolog, programın baģ kısmının doğru olduğunu ispatlayabilir. 2. Gerçekler ve kurallar birbirinin aynısıdır. Gerçeklerin kurallardan tek farkı, açıklayıcı bilgi taģıyan gövdelerinin olmamasıdır. 3. Prolog a bir dizi gerçek veya kural tanıttıktan sonra, bu gerçekler veya kurallar hakkında soru sormak mümkündür. Buna Prolog Sistemini Sorgulama denir. Prolog, sorgulama esnasında, verilen gerçekler listesinin baģından sonuna kadar tarama yapar ve sorguya uyan cevapları bulmaya çalıģır. 4. Prolog daki Karar Motoru bir kuralın baģ ve gövde kısmını incelerken, bilinen gerçek ve kurallara baģvurur. ġartların yerine gelip gelmediğini kontrol eder. Bir kuraldaki bütün Ģartlar doğrulandıktan sonra, bağımlı olan kısım, yani kuralın baģ kısmının doğru olduğuna karar verir. Bütün Ģartlar, bilinen gerçeklere göre karģılanamazsa, sorguya olumlu cevap verilemez. Örnekler: Prolog gerçeklerinin konuģma diline çevrilmesi, aģağıda verilmiģtir. 1. yapmaktan_hoslanir(oya, resim) = Oya, resim yapmaktan hoģlanır. 2. cocuk(arif).= Arif, bir çocuktur. 3. bulunur( Çankaya KöĢkü, Ankara ). = Çankaya KöĢkü Ankara dadır. 8

19 4. adres(abuzer, zonturlu, Fatih Cad. 6. Sokak., DıĢkapı, ANKARA, 06412).= Abuzer Zonturlu nun adresi Fatih Cad. 6. Sokak DıĢkapı, ANKARA, dir. ġimdi tam tersini yapalım, konuģma dilinden Prolog diline çevrilme ise, aģağıdaki gibi yapılır. 1. Vedat iyi kebap yapar = yapar(vedat, iyi_kebap). 2. Keban Barajı Elazığ dadır = bulunur( Keban Barajı, Elazığ ). 3. Kasım Kaya nın telefon numarası dir. telefon_no( Kasım KAYA, ). 4. Hüseyin Meryem in babasıdır. = baba(huseyin, meryem) Konuşma Dilindeki Cümlelerin Prolog Programlarına Aktarılması Bu bölümün ilk kısmında gerçekler, kurallar, iliģkiler, genel cümleler ve sorgulamalar konusunu incelenmiģtir. Aynı kelimeler üzerinde çalıģmakla beraber, Prolog la daha fazla ilgili kelimeler üzerinde, yani cümlecikler, yüklemler, değiģkenler ve hedefler üzerinde durulacaktır Cümleler (Gerçekler ve Kurallar) Prolog dilini oluģturan iki türlü ifade vardır. Bu ifadeler gerçekler veya kurallardan ibarettir. Prolog dilinin kalbini oluģturan bu ifadelere clause denilmektedir. Bir gerçek, bir nesnenin veya nesneler arasındaki iliģkinin bir özelliğinin sadece tek bir yönünü temsil eder. Bir gerçeğin Prolog tarafından tamamen doğru kabul edildiğini, bir sorgulamaya cevap ararken bu gerçeklerden yola çıkıldığını ve bu gerçeklerin doğruluğunun kontrol edilmediği unutulmamalıdır. Günlük hayatımızda da doğruluğu bilinen gerçeklerden yola çıkarak bir Ģeyin doğru olup olmadığı araģtırlır. ĠĢte, mevcut gerçeklerden hareket ederek neyin doğru olabileceğini gösteren yapıya Prolog da Kural denir. ġimdi Prolog daki Kural yapısına bir örnekle yakından bakalım. Örnek: 1. AĢağıdaki cümlede, menü de olan bir yemeğin Mehmet e uygun olup olmadığı sorgulanmaktadır. Mehmet ülser olduğu için sadece doktorunun izin verdiği yemekleri yer. 9

20 Menü ve yukarıdaki kurala bakarak, Mehmet in hangi yemeği sipariģ edebileceğine karar verilebilir. Bunu yapabilmek için, menüdeki yemeğin belirli Ģartları taģıyıp taģımadığına bakılmaladır. a. Menudeki_yemek bir sebze mi? b. Menudeki_yemek doktorun tavsiye ettiği listede var mı? c. Sonuç: Eğer a ve b Ģıklarının ikisinin de cevabı Evet ise, bu durumda Mehmet menüdeki bu yemeği yiyebilir. Prolog da bu tür iliģkilerin bir kuralla ifade edilmesi zorunludur, çünkü verilecek karar tamamen gerçeklere bağlıdır. Yukarıdaki ifadeler; Prolog gerçekleri olarak Ģöyle yazılabilir: mehmet_yiyebilir(menudeki_yemek):- sebze(menudeki_yemek), doktor_tavsiyeli(menudeki_yemek). sebze(menudeki_yemek) ifadesinden sonra, konulmuģtur. Çünkü virgül, iki amaç arasındaki bağlantıyı gösterir ve and anlamındadır. mehmet_yiyebilir(menudeki_yemek) iliģkisinin doğrulanabilmesi için, sebze(menudeki_yemek), doktor_tavsiyeli(menudeki_yemek) iliģkilerinin her ikisinin de doğru olması gerekir. Örnek: Ebeveyn iliģkisini anlatan bir Prolog gerçeği aģağıdaki gibi yazılır. ebeveyn(omer, nejla) = Omer, Nejla nın ebeveynidir. Programın veritabanında babalık durumunu gösteren gerçeklerin zaten var olduğunu, yani baba(omer, nejla) gerçeğinin mevcut olduğu ve aynı zamanda annelik iliģkisini de gösteren anne(leyla, nejla) gerçeğinin de var olduğu kabul edilsin. Babalık veya annelik bağı hakkında yeterince bilgi olduğundan, ayrıca baba ve anne bilgilerini anlatmak vakit kaybına neden olur. Bunu yerine genel bir kural yazmak daha mantıklıdır. Yani, ebeveyn(sahis1, Sahis2):-baba(Sahis1, Sahis2). ebeveyn(sahis1, Sahis2):-baba(Sahis1, Sahis2). Örnek: Bir müģteri arabayı severse ve araba satılık ise bu arabayı satın alabilir. Tabii dildeki bu iliģki, aģağıdaki kuralla Prolog a aktarılabilir: 10

21 satin_alabilir(musteri, Model):- sahis(musteri), araba(model), hoslanir(musteri, Model), satilik(model). Aynı kural, konuģma dilinde aģağıdaki Ģekilde ifade edilir. MüĢteri modeli satın alabilir :- MüĢteri bir Ģahıs ve Model bir araba ve MüĢteri modelden hoģlanırsa ve Model satılık ise. Bu kuralın baģ kısmı, gövde kısmındaki her dört Ģartın da doğrulanması halinde doğru olacaktır. Yukarıda yazılan gerçekler, aģağıdaki Ģekilde program haline getirilebilir. PREDICATES nondeterm satin_alabilir(symbol, symbol) nondeterm sahis(symbol) nondeterm araba(symbol) hoslanir(symbol, symbol) satilik(symbol) CLAUSES satin_alabilir(x,y):- sahis(x), araba(y), hoslanir(x,y), satilik(y). sahis(ahmet). sahis(paki). sahis(cengiz). sahis(levent). araba(buick). araba(bmw). araba(passat). araba(toyota). 11

22 hoslanir(paki,buick). hoslanir(levent, toyota). hoslanir(cengiz, passat). hoslanir(ahmet, tenis). satilik(pizza). satilik(toyota). satilik(buick). satilik(passat). Yukarıdaki programı yazdıktan sonra Levent ve Cengiz in ne satın alabileceğini, kimin buick marka arabayı alabileceğini bulmak için aģağıdaki hedef cümleleri kullanılabilir: satin_alabilir(kim, Ne). satin_alabilir(levent, Ne). satin_alabilir(cengiz, Ne). satin_alabilir(kim, buick) Olgular Arasındaki İlişkiler: Yüklemler (Predicates) Bir iliģkinin sembolik ismine yüklem denir ve yükleme bağlı olan nesnelere argüman denir. Mesela sever(yasin, esra) gerçeğindeki sever iliģkisi yüklem, yasin ve esra ise bu yüklemin agrümanları olan nesnelerdir. Argümanlı ve agrümansız yüklem örnekleri: sahis(soyad, ad, cinsiyet). sahis yüklem; soyad, ad, cinsiyet ise bu yüklemin argümanlarıdır. basla = argümanı olmayan yüklem dogum_gunu(isim, soyisim, tarih). Dogum_gunu yüklem, isim, soyisim ve tarih nesneleri ise argümanlarıdır. Sınırlı olmakla beraber, bir yüklem argümansız olarak da kullanılabilir Değişkenler (Genel Cümleler) Basit bir sorgulamada, sever(kim, tenis) kuralını kullanarak kimin tenis oynamaktan hoģlandığı öğrenilebilir. Bu sorguda Kim, değiģken olarak kullanılmıģtır. 12

23 Visual Prolog da değiģken isimlerinin daima büyük harfle veya _ ile baģladığı, daha önceden söylenmiģti. Ġlk karakteri büyük bir harf veya _ olmak Ģartıyla, değiģkenler istenilen kadar rakam, büyük veya küçük harf alabilirler. Konu ile ilgili birkaç örnek, aģağıda verilmiģtir. Geçerli Değişkenler Geçersiz Değişkenler Prolog_ile_yazdigim_ilk_program 1.deneme _14_10_1978_tarihinde_doganlar 14.program _1_nolu_ogrenci prolog DeğiĢken ismi seçimine dikkat etmek, programın baģkaları tarafından rahat bir Ģekilde okunması ve anlaģılması bakımından önemlidir. sever(kim, tenis) kuralı sever(x, tenis) kuralına tercih edilir. Çünkü Sahis X e göre daha fazla anlamlıdır Prolog da Değişkenlerin Değer Alması Diğer programlama dillerinde, değiģkenlerin değer almalarına imkan tanıyan atama ifadeleri Prolog da yoktur. Prolog u diğer programlama dillerinden ayıran en önemli özelliklerden biri de budur. Prologdaki değiģkenler almaları gereken değerleri atamayla değil, gerçekler veya kurallardaki sabitlere eģleģtirilirken alırlar. Bir değiģken, değer almadığı müddetçe serbest değiģken olarak kalır. Fakat herhangi değer aldığı andan itibaren sınırlı hale gelir. Bu sınırlılık bir sorguya cevap almak için gerekli olan süre kadar sınırlı kalır. Bu iģlem bittikten sonra değiģken yeniden sınırlı hale gelir, program baģa döner ve alternatif çözümler arar. Dolayısıyla bir değiģkene bir değer vererek bilgi depolanamaz. DeğiĢkenler bilgi depolamak için değil, kalıp-eģleģtirme ve iģlemenin bir parçası olarak kullanılır. PREDICATES nondeterm sever(symbol, symbol) CLAUSES sever(oktay, okuma). sever(yavuz, bilgisayar). sever(orhan, tavla). sever(vedat, uyuma). sever(ismail, yuzme). 13

24 sever(ismail, okuma). Hem okuma hem de yüzmeden kimin hoģlandığı sorusuna cevap aramak için Ģu sorguyu kullanılır. GOAL sever(sahis, okuma), sever(sahis, yuzme). Prolog bu kuralı çözmek ve önce sever(sahis, okuma) kısmının doğru olup olmadığını bulmak için bütün gerçekleri baģtan sonra kadar inceler. Çözüm bulunmadan önce Sahis değiģkeninin değeri yoktur, yani serbesttir. Öte yandan okuma kısmı bilinmektedir. Ġlk sever(oktay, okuma) gerçeğindeki okuma kısmı sorguya uyduğu için Sahis oktay değerini alır. Prolog aynı zamanda aģağıya doğru nereye kadar tarama yaptığını göstermek için kuralın baģıyla eģleģen ilk noktaya bir pointer koymaktadır. Sorgunun ilk kısmı doğrulandıktan sonra ikinci kısmının da doğrulanması gerekir. Yani yüzmeden hoģlanan kiģinin de bulunması gerekir. Sahis değiģkeni oktay değeri aldığı için artık sever(oktay, yuzme) gerçeğinin doğru olup olmadığı araģtırılır. Gerçekler incelenirse, oktay isimli Ģahsın yüzmeden hoģlanmadığı görülür. Bu durumda Prolog Sahis değiģkenine atadığı oktay değerini etkisiz hale getirir ve Sahis yeniden serbest hale gelir. Kuralın ilk kısmını doğrulayan gerçeği bulmak için Prolog bu kez kuralların baģından değil, gerçekler listesine daha önce yerleģtirmiģ olduğu pointer den aģağıya kadar doğru taramaya baģlar. Ġlk gerçek gereken Ģartları sağlayamadığı için artık dikkate alınmaz. Bu iģleme Geriye İz Sürme denir. Yapılan taramada okumadan hoģlanan kiģinin ismail olduğu görülünce Sahis değiģkeni bu kez ismail değerini alır. Kuralın ikinci kısmının doğrulanması için tarama yapılırsa, yüzme için gereken Ģartın yine ismail ile sağlandığı görülür. Dolayısıyla Prolog un vereceği cevap Ģu olur: Sahis=ismail 1 Solution Anonim Değişkenler Anonim değiģkenler, programların gereksiz bilgi ve satırlarla karmaģık hale gelmelerini engeller. Böylece bir sorgulamadan beklenilen bilgileri alabilir ve ihtiyaç olmayan değerler iptal edilmiģ olur. Prolog da anonim değiģkenler _ ile gösterilir. 14

25 AĢağıdaki örnekte anonim değiģkenin kullanımı verilmiģtir: PREDICATES erkek(symbol) bayan(symbol) nondeterm ebeveyn(symbol, symbol) CLAUSES erkek(selahattin). erkek(cihat). bayan(sacide). bayan(sezen). ebeveyn(selehattin, cihat). ebeveyn(sacide, cihat). ebeveyn(selehattin, sezen). GOAL ebeveyn(ebeveyn,_). Diğer değiģkenlerin yerine kullanılabilen anonim değiģkenlerin, normal değiģkenlerden tek farkları Ģudur: anonim değiģkenler hiçbir zaman bir değere eģitlenemezler. Yukarıdaki örnek yazdıktan sonra GOAL ebeveyn(ebeveyn,_) sorgusu çalıģtırılarak, ebeveyn olan kiģilerin isimleri öğrenilebilir. Çocukların isimleri istenmediği için isimlerinin yerine anonim değiģken kullanılmıģtır. Programın sonucunda Ģu sonuç görüntülenir: Ebeveyn=selehattin /*Cihat ın ebeveyni */ Ebeveyn=sacide /* Cihat ın ebeveyni*/ Ebeveyn=selehattin /* Sezen in ebeveyni*/ 2 solutions Tanımlanan değiģken anonim olduğu için, alınacak cevabın ikinci argümanla bağlantısı olmayacaktır. Anonim değiģkenler, gerçeklerin tanımlanmasında da kullanılabilir. vardir(_,televizyon). yemek_yer(_). 15

26 Ġfadeleri konuģma dilinde Herkesin televizyonu var ve Herkes yemek yer olarak çevrilebilir Hedefler (Sorgular) ġimdiye kadar Prolog a soru sormak anlamında kullanılan sorgulama kelimesinin yerine bu andan itibaren Hedef(Goal) kelimesi kullanılacaktır. Sorgulamaları hedef olarak tanımlamak daha anlamlıdır, çünkü Prolog a bir sorgu yöneltmekle, ona yerine getirilmesi gereken bir hedef verilmiģ olur. Hedefler sever(ismail, yuzme) gibi basit olabileceği gibi sever(sahis, okuma), sever(sahis, yuzme) gibi daha karmaģık da olabilir. Birden fazla parçadan oluģan hedefe Birleşik Hedef, her bir parçaya da alt hedef denir Birleşik Hedefler: Bağlaçlar ve Ayraçlar BirleĢik bir hedefin çözümünü bulmak için her iki alt hedefin doğru olması gerekir. Bu durumda, iki alt hedef arasında (ve) anlamına gelen, kullanılır. Fakat istenilen durumlarda alt hedeflerden sadece birinin doğru olması Ģartı da aranabilir. Bu durumda alt hedefler arasında (veya) anlamına gelen ; kullanılması gerekir. Bu duruma Ayırma işlemi denilmektedir. ġimdi bu durumu gösteren bir örnek inceleyelim: PREDICATES nondeterm araba(symbol,long,integer,symbol,long) nondeterm kamyon(symbol,long,integer,symbol,long) nondeterm arac(symbol,long,integer,symbol,long) CLAUSES araba(chrysler,130000,3,kirmizi,12000). araba(ford,90000,4,gri,25000). araba(datsun,8000,1,kirmizi,30000). kamyon(ford,80000,6,mavi,8000). kamyon(datsun,50000,5,sari,20000). kamyon(toyota,25000,2,siyah,25000). arac(marka,kilometresi,yas,renk,fiyat):- 16

27 araba(marka,kilometresi,yas,renk,fiyat); kamyon(marka,kilometresi,yas,renk,fiyat). GOAL araba(marka, Kilometresi, Kullanim_Suresi, Renk, 25000). Bu örnekteki hedef, cümleciklerde tarif edilen dolarlık arabayı bulur. Benzer Ģekilde; fiyatı dolardan daha az olan bir araba var mı? Ģeklindeki bir soruya cevap bulmak da mümkündür. Bunun için araba(marka, Kilometresi, Kullanim_Suresi, Renk, Fiyat), Fiyat< Ģeklindeki bir sorguyla bu sorunun cevabını bulmak mümkündür. Bu kuralı sorgulandığında, alınacak cevap chrysler olacaktır. ġimdi fiyatı dolardan az olan bir araba veya fiyatı dolardan daha az olan bir kamyon var mıdır? Ģeklindeki bir soruya uygun bir hedef yazalım: araba(marka, Kilometresi, Kullanim_Suresi, Renk, Fiyat), Fiyat< 25000; kamyon (Marka, Kilometresi, Kullanim_Suresi, Renk, Fiyat), Fiyat< Prolog ilk önce fiyatı dolardan daha az olan bir araba olup olmadığını araģtırır. Sonuç doğru olsun veya olmasın, ikinci alt hedef de araģtırılır. Her ikisinden birinin doğru olması durumunda alınacak cevap olumlu olacaktır. Hedefin doğrulanması için birden fazla alt hedefin aynı anda doğru olması gerekmez. Bu tür hedeflere ayrıştırma denilmektedir ve bunun için alt hedefler arasında ; ayracı kullanılmaktadır Açıklama Satırları Program yazarken program satırları arasına açıklamalar yazmak, baģkalarının da programı okuyup anlamasına imkan tanır. Program içerisine yazılan bu yorum satırları derleyici tarafından dikkate alınmaz. Prolog da yorum satırları bir kaç satırdan oluģacaksa /* ile baģlamalı ve */ ile bitmelidir. Eğer tek bir satır yorum yazılacaksa % iģareti kullanılabilir. /* Program yazarken kullanılan değiģkenler, yüklem ve kurallar*/ /*hakkında bilgi vermek için bu tür yorum satırları yazılabilir*/ %Tek satırlık yoruma bir örnek. /* Ġç içe /* yorum */ satırı yazmak da mümkündür*/ 17

28 2.14. Eşleştirme Prolog da eģleģtirme yapılırken eģlenik yapılar birbiriyle eģleģebilir. ebeveyn(selehattin, X), ebeveyn(sacide, cihat) kuralındaki X değiģkeni cihat değerini alır ve serbest olan bu değiģken artık bağlı hale gelir. Bağlı hale gelen baģka bir değiģkene atanırsa, diğer değiģken de aynı değeri alır Bölüm özeti 1. Prolog da bir program gerçekler ve kurallardan oluģan cümleciklerden oluģur. Gerçekler, doğru oldukları kabul edilen iliģkiler ve özelliklerdir. Kurallar bağımlı iliģkiler olup, gerçekler ve iliģkileri kullanarak bilgi elde etmeye yararlar. 2. Gerçeklerin genel yazılıģ biçimi Ģöyledir: ozellik(nesne1, nesne2,... nesnen) veya iliģki(nesne1, nesne2,... nesnen) Burada özellik nesnelerin herhangi bir özelliği, iliģki ise nesneler arasındaki herhangi bir iliģkidir. Özellik ve iliģki kelimelerinin her ikisi de Prolog da aynı anlamda kullanılır. 3. Bir programda verilen bir iliģki bir veya daha fazla nesne arasındaki iliģkiden ibarettir. sevmek(ahmet, futbol) gerçeğindeki sevmek bir iliģkiyi, ahmet ve futbol ise bu iliģkinin nesnelerini temsil eder. solak(hasan) gerçeğinde solak bir özelik, hasan ise bir nesnedir. 4. Kuralların genel yazılma Ģekli: BaĢ:-Gövde olup, daha açık hali aģağıdaki gibidir. iliģki(nesne, nesne,..., nesne) :- iliģki(nesne, nesne,..., nesne),.. iliģki(nesne, nesne,..., nesne). 18

29 5. ĠliĢki ve nesne isimlerinin yazılması bazı kurallara bağlıdır. Nesne ve iliģki isimleri daima küçük harfle baģlar. Bunu takiben istenilen sayıda büyük-küçük harf, rakam, _ kullanılabilir. 6. DeğiĢken isimleri daima büyük bir harf veya _ ile baģlar. Bunu takiben istenildiği kadar küçük_büyük harf, rakam vs. kullanılabilir. DeğiĢkenler bir değer almadan önce serbest, değer aldıktan sonra ise bağlı hale gelirler. Bir değiģkene değer atayıp bilgi depolamak mümkün değildir. Çünkü bir değiģken sadece bir cümlecikte bağımlıdır. 7. Bir sorgudan sadece belirli bir bilgi alınmak isteniyorsa, anonim değiģken (_) kullanılabilir. Anonim değiģkene hiçbir zaman değer atanması yapılamaz. 8. Prolog a programda verilen gerçeklere göre bir soru sormak Prolog Sistemini Sorgulama olarak adlandırılır ve bu sorguya Hedef denir. BileĢik bir hedef iki veya daha fazla hedeften oluģur. Bu parçaların her birine alt hedef adı verilir. BileĢik hedefler Bağlaç veya Ayraç Ģeklinde olabilir. 10. EĢleĢtirme birbirine denk yapılar arasında gerçekleģtirilir. Serbest bir değiģken bir sabite veya önceden değer alıp bağımlı hale gelmiģ baģka bir değiģkene atanabilir. Serbest olan iki değiģken birbirine atanırsa, birinin alacağı değer otomatik olarak diğerine atanmıģ olur. 19

30 3. VISUAL PROLOG PROGRAMLARININ TEMEL BÖLÜMLERİ Bir VIP Programı genelde Ģu dört bölümden oluģur: Clauses (Gerçekler ve Kurallar), Predicates (Yüklemler), Domains (DeğiĢken Tipleri) ve Goals(Hedefler) Clauses(Olgular veya Kurallar) Bu bölüm bir programın kalbi durumundadır. Çünkü programda tanımlı hedefler doğrulanmaya çalıģılırken, doğruluğu daha önceden bilinen gerçeklerden yola çıkılır. Gerçek ve gerçekler arasındaki iliģkileri tanımlayan kuralların tanımlandığı yer bu bölümdür. Bir yüklem için tanımlanması gereken bütün clauselar kümesine Procedure denir Predicates (Yüklemler) Yüklemlerin ve yüklemlerdeki argümanların tiplerinin tanımlandığı yer bu bölümdür. Visual Prolog da mevcut olan hazır yüklemlerin tanımlanması gerekmez Domains (Değişken Tipleri) Burada, Visual Prolog da olmayan tiplerin tanımlanması yapılır Goal (Hedef) Programdaki sorgular buraya yazılır Yüklem Tanımı Bir yüklemin genel yazılıģ biçimi Ģöyledir: yuklem_adi(argüman_tip1, argüman_tip2, argüman_tip3,..., argüman_tipn) Yüklemlerin bitiģ parantezinin clauses bölümündeki gibi. ile sonlanmadığına dikkat edilmelidir. Yüklem isimleri en fazla 250 karakterten oluģabilir ve herhangi bir harfle baģlayabilir. Yüklemler için isim seçilirken küçük veya büyük harfle baģlamak önemli değildir. Fakat küçük bir harfle baģlayan bir isim seçilmesi önerilir. Çünkü Prolog derleyicilerin çoğu ancak küçük harfle baģlayan yüklem isimlerini kabul etmektedir. Kullanılabilecek karakterler Ģunlardır: 20

31 Büyük harfler: A, B,..., Z Küçük harfler: a, b,..., z. Rakamlar: 0, 1,..., 9 Alt tire: _. Geçerli Yüklem Ġsimleri Olgu Oynar sahip_olunan_servet tahakkuk_fisi 10_kisilik_sinif Geçersiz Yüklem Ġsimleri [olgu] *gider* Sahiptir/araba bu-ayin-bordrosu <10-kisiden_biri Örnekler: domains isim=symbol numara=integer predicates ilk_yuklem(isim, numara) domains sahis, eylem=symbol araba, marka, renk=symbol kilometresi, kullanim_yili, fiyat=integer predicates sever(sahis, eylem) ebeveyn(sahis, sahis) satin_alabilir(sahis, araba) araba(marka, kilometresi, kullanim_suresi, renk, fiyat) yesil(symbol) derece(symbol, integer) Yukarıdaki program parçasında yüklem ve argümanların anlamları aģağıda verilmiģtir. 21

32 sever yüklemi iki argüman alır: sahis ve eylem. Bu argümanların her ikisi de değer olarak symbol, yani alfabetik karakterler alabilir. ebeveyn yükleminin iki argümanı da sahis olup, domainde tanımladığı Ģekliyle symbol tipindedir. satin_alabilir yüklemi tipi symbol olan sahis ve araba argümanlarını almıģtır. araba yüklemi 5 adet argüman almıģtır. Ġlk ikisinin tipi symbol, son üçünün ise integer dır (tamsayı). yesil yüklemi, tipi symbol olan tek bir argüman almıģtır. Symbol tipi zaten Visal Prolog un standart tipleri arasında yer aldığından, ayrıca tanımlamaya gerek yoktur. derece yükleminin argümanları da standart domain de yer almaktadır Domains (Tip tanımları) Bölümü Domain kısmında argümanların tipleri tanımlanır. Bir argüman alfabetik, nümerik veya her ikisinden oluģan karakterleri değer olarak alabilir. Domain kısmı, birbirinin aynısı gibi görünebilecek verilere farklı isimler vermemize imkan tanır. VIP programlarında iliģki veya gerçeklerde tanımlanmıģ olan nesneler (yüklemdeki argümanlar) domainlere aittir. Bu tipler standart olarak tanımlı olabileceği gibi, kullanıcı tarafından sonradan da tanımlanabilir. Domain kısmı son derece faydalı iki görev icra eder. Birincisi, yüklemlerde tanımlanan argümanların tipleri VIP de standart olarak tanımlamıģ olan symbol, tamsayı vs. domainleri olsalar bile, argümanlara farklı anlamlı isimler vermemize imkan tanır. Ġkincisi, standart domainler tarafından tanımlanmamıģ veri yapılarını tanımlanmasına imkan sağlar. Ayrıca, yüklemdeki argümanların net olarak anlatılabilmesi için farklı domainler olarak tanımlanması da faydalıdır. Örnekler: 1. AĢağıdaki tabii dil cümlesinin VIP de karģılığını yazıp, özel domain tanımı aģağıdaki Ģekilde yapılır. Hasan, 28 yaģında bir erkektir. 22

33 Eğer özel olarak domain tanımlanmazsa, yani VIP deki standart tipler kullanılırsa yukarıdaki cümle Ģöyle yazılabilir: sahis(symbol, symbol, integer) Bu yüklem ve argümanlar doğru biçimde tanımlandığı için çalıģır. Fakat sahis yüklemi içinde tanımlanan üç argümanın neye iģaret ettiğini hatırlamak zor olabilir. Bunun yerine: domains isim, cinsiyet = symbol yas = integer predicates sahis(isim, cinsiyet, yas) Ģeklinde üç ayrı domain tanımlanırsa sahis argümanındaki isim, cinsiyet ve yas argümanlarının anlamı her zaman için barizdir. Bu tanımlamanın bir faydası da argüman tipleri arasında olabilecek tip eģleģtirme hatalarını önlemektir. Özel domainler, argümanların anlamını çok daha iyi ifade ettikleri halde, bütün argümanlar için özel domain kullanmak gerekmez. Bir argüman için belli bir tip tanımlanması yapıldıktan sonra, bu argüman, tipi aynı olan bir baģka argümanla hiçbir Ģekilde karıģtırılmaz. Örneğin isim ve cinsiyet argümanlarının her ikisinin de tipi symbol olmasına rağmen birbiriyle karıģtırılmazlar. Fakat kullanıcının tanımladığı argümanların hepsi önceden tanımlanmıģ argümanlarla karıģtırılabilir. AĢağıdaki örnek, çalıģtırıldığı zaman bir tip hatası verir. DOMAINS carpma, toplam = integer PREDICATES toplama_yap(toplam, toplam, toplam) carpma_yap(carpma, carpma, carpma) CLAUSES toplama_yap(x, Y, Toplam):- Toplam=X+Y. carpma_yap(x, Y, Carpma):- Carpma=X*Y. 23

34 GOAL toplama_yap(32, 54, Toplam). Buradaki GOAL toplama_yap(32, 54, Toplam) doğru çalıģır ve Toplam=86 1 Solution cevabı alınır. Carpma_yap fonksiyonu için 35 ve 25 değerlerleri kullanılırsa, Carpma=875 1 Solution sonucu alnır. 31 ve 17 sayılarının çarpımını bulup, elde edilen sayıyı kendisiyle toplayıp Cevap argümanının değeri aģağıdaki Ģekilde bulunur. carpma_yap(31, 17, Toplam), toplama_yap(toplam, Toplam, Cevap) Ģeklinde bir hedef yazılabilir. Bu hedefe göre, bulunacak sonucun Toplam=527 (31*17), Cevap=1054 ( ) olması gerekirken, VIP derleyici bir hata mesajı verir. Çünkü carpma_yap fonksiyonundaki Toplam argümanı 527 değerini aldıktan sonra bu değeri ikinci yüklem olan toplama_yap taki ilk iki argümana taģımaya çalıģır. Her iki argüman da tamsayı tipinde olmasına rağmen farklı isimlerde olduklarından, birbirleriyle eģleģtirilemezler ve neticede hata mesajı görüntülenir. Bu yüzden bir cümledeki fonksiyonda tanımlanan değiģken birden fazla fonksiyonda kullanılacaksa, her fonksiyonda aynı Ģekilde tanımlanmalıdır. Örnek: DOMAINS marka, renk = symbol yas=byte fiyat, yol=ulong PREDICATES nondeterm araba(marka, yol, yas, renk, fiyat) CLAUSES araba(chrysler,130000,3,kirmizi,12000). araba(ford,90000,4,gri,25000). araba(datsun,8000,1,siyah,30000). 24

35 GOAL araba(renault, 13, 40000, kirmizi,12000). GOAL araba(ford, 90000, gri, 4, 25000). GOAL araba(1, kirmizi, 30000, 80000, datsun). Burada araba yükleminin 5 argümanı mevcuttur. Yas argümanı byte tipinde olduğu için alabileceği değer 8 bitlik ve arasında değiģen pozitif bir sayıdır. Aynı Ģekilde yol ve fiyat tipleri ulong (uzun tamsayı) olup 32-bit pozitif tamsayı değerleri alır. Son olarak marka ve renk tipleri symbol tipindedir. Yukarıdaki sorguları tek tek deneyince her birinin ayrı bir tip hatasına neden olduğu görülecektir. GOAL araba(renault, 13, 40000, kirmizi, 12000) sorgusunda byte tipinde olması gereken yas argümanı değerini almıģtır. Bunun arasında olması gerekir. Ġkinci sorguda yas ve renk argümanlarının değerleri yer değiģtirmiģtir. Bu nedenle yine hataya neden olur Goal Bölümü Goal bölümünün bir kuralın yapısından sadece iki farkı vardır. 1. Goal kelimesinden sonra if anlamındaki :- operatörü kullanılamaz. 2. Program çalıģırken VIP ilk önce GOAL satırını çalıģtırır Deklarasyon ve Kurallara Ayrıntılı Bakış Bir yüklemdeki argümanların tiplerini tanımlarken, VIP de hazır bulunan standart tipler kullanılabilir. Bu tiplerin domains kısmında, ayrıca tanımlanması gerekmez. AĢağıdaki tabloda hazır olarak bulunan tipler verilmiģtir (Tablo 1). Tablo 3.1: Visual Prolog da Tipler ve Alabilecekleri değerler. Tip Kullanıldığı Yer Değer Aralığı short Bütün Platformlar 16 Bit Ushort Bütün Platformlar 16 Bit Long Bütün platformlar 32 bit Ulong Bütün platformlar 32 bit İnteger (Bilgisayar ve Mimariye bağlı olarak - veya + değer alabilir) 16 Bit Platformlar 32 Bit platformlar 16 Bit 32 Bit Unsigned (Bilgisayar ve mimariye bağlı olarak -/+ değer alabilir) 16 Bit Platformlar 32 Bit platformlar 16 Bit 32 Bit byte Bütün platformlar 8 bit Word Bütün platformlar 16 bit Dword Bütün platformlar 32 bit

36 Her değiģken tipi verilen aralıkta bulunan bir değeri alabilir. Integer ve unsigned tipleri, değiģkenlerin tanımlandığı bilgisayar veya sistemlere göre değiģen aralıktaki değerleri alırlar. Domain tanımı yapılırken signed veya unsigned kelimeleri byte, word ve dword domainleri ile birlikte kullanılabilirler. Domains i8 = signed byte tanımı normalde unsigned olan ve bu yüzden aralığından değer alan byte yerine değerleri arasında değer alan bir tip haline gelir Char ĠĢaretsiz bir byte olarak kullanılır. Örnek: A, b Real +/- DDDD.DDDD Ģeklinde olan 8 bitlik bir değiģken. (1* * ) String 255 karakter uzunluğunda olabilen bu tipin iki formatı vardır. a) Ġlki küçük harf olmak üzere harf, sayı veya altçizgiden oluģur. b) Çift tırnak arasına alınmıģ karakterlerden oluģur. Örnek Örnekler: Adı_soyadı, MüĢterinin Adı, Fox Ltd Symbol Formatı string ler ile aynıdır. Symbol ve string değiģkenler birbirinin aynısı olmakla beraber, VIP bunları farklı Ģekillerde depolar. Symbol tipleri bir tabloda saklanır. Adresleri ise nesneleri temsil edecek Ģekilde saklanır. Böylece eģleģtirme iģleminde hızlı kullanılırlar. Fakat karģılaģtırmalarda String tipler karakter bazında eģleģtirilir. 26

37 3.9. Yüklemlerdeki Argümanların Yazılması Predicates bölümündeki bir argümanın tipini tanımlamaya, argüman tipi tanımlama denilmektedir. Hasan, 28 yaģında olan bir erkektir = sahis(hasan, erkek, 28). Sahis bu argümanlarla birlikte kullanan bir yüklem olarak tanımlamak için aģağıdaki satırın predicates bölümünde yazılması gerekir. sahis(symbol, symbol, unsigned) Görüldüğü gibi her üç argüman da standart tipte tanımlanmıģtır. Yani, program içerisinde her ne zaman sahis yüklemi geçerse, bu yüklemi sadece 3 argümanla birlikte kullanılabilir. Bunların ilk ikisi symbol, üçüncüsü ise unsigned tipinde bir integer olmalıdır. Alfabedeki bir harfin yerini belirleyen alfabedeki_yer(harf, Yer) Ģeklinde bir iliģkiyi incelendiğinde, Harf ve Yer argümanlarının her ikisi de değiģken olarak tanımlandığı görülür. Böylece Harf=a ise Yer=1, Harf=b ise Yer=2 vs. Ģeklinde devam eder. Bu durum kısaca Ģöyle ifade edilebilir. alfabedeki_yer(bir_harf, N). Bunun için yazılması gereken olgular: alfabedeki_yer( a, 1). alfabedeki_yer( b, 2). alfabedeki_yer( c, 3).... alfabedeki_yer( z, 29.) Ģeklinde olmalıdır. PREDICATES alfabedeki_yer(char, integer) CLAUSES alfabedeki_yer( a, 1). alfabedeki_yer( b, 2). alfabedeki_yer( c, 3). GOAL alfabedeki_yer( c, Nerede). Program çalıģtırıldığında c harfinin yerini veren Nerede değiģkeni 3 değerini alır. 27

38 Örnek: DOMAINS adi_soyadi, tel_no = symbol PREDICATES nondeterm telefon_numarasi(adi_soyadi, tel_no) CLAUSES telefon_numarasi("orhan AYDIN", " "). telefon_numarasi("arif GÜREL", " "). telefon_numarasi("husamettin BULUT", " "). telefon_numarasi("kasim YENIGÜN", " "). Bu program, aģağıdaki sorgularla veya yenileri ilave edilerek çalıģtırılabilir. GOAL telefon_numarasi(kimin_telefonu, " "). GOAL telefon_numarasi("orhan AYDIN", Telefon_Numarasi). GOAL telefon_numarasi(telefon_sahibinin_adi, Telefon_Numarasi). Örnek: Ekrandan girilen bir karakterin harf olup olmadığını kontrol eden bir program yazınız. (Not: char tipi sadece bir tek karakteri tanımlar) REDICATES nondeterm aranan_harf(char) CLAUSES aranan_harf(harf):- a <=Harf, Harf<= z. aranan_harf(harf):- A <=Harf, Harf<= Z. GOAL aranan_harf( x ). aranan_harf( 2 ). aranan_harf( Merhaba ). aranan_harf( a ). aranan_harf(x). 28

39 Yukarıdaki program, verilen bir karakterin alfabenin bir harfi olup olmadığını test etmektedir. Yazılan sorguları kullanarak elde edilen sonuçları inceleyiniz. Bazı Ģıklarda neden hata verdiğini bulmaya çalıģınız. Predicate bölümünde aynı isimde birden fazla yüklem tanımlanabilir. Fakat bunların argümanlarının farklı sayıda olması gerekir. Predicates ve Clauses bölümlerinde aynı isimde olanların birlikte gruplanmaları gerekir. Bu yüklemler, tamamen farklıymıģ gibi iģlem görürler. Örnek: DOMAINS sahis=symbol PREDICATES baba(sahis) %Buradaki Ģahıs bir babadır. baba(sahis, sahis) %Buradaki birinci kiģi ikinci kiģinin babasıdır. CLAUSES baba(insan):-, baba(insan, _). baba(ahmet, mehmet). baba(omer, yavuz) Kuralların Yazım Biçimi VIP de kurallar, BaĢ ve Gövde olmak üzere iki kısımdan meydana gelir. Genel Biçim: BaĢ:- <alt hedef1>, <alt hedef2>,..., <alt hedefn>. Alt hedefler biribirinden, ile ayrılır ve sonuncusu nokta ile biter. Alt hedeflerin her biri ayrı bir yüklem çağırır. Alt hedefin doğru olup olmadığı kontrol edilir. Sonuç ne olursa olsun, bu iģlem bütün alt hedeflere uygulanır. Alt hedeflerin tamamının olumlu netice vermesiyle beraber o kuralın doğruluğu ispatlanmıģ olur. Sadece bir alt hedef bile yanlıģ olursa, bütün kural yanlıģ olur. 29

40 3.11. Prolog ve Diğer Dillerdeki if Komutunun Karşılaştırılması VIP de baģ ve gövde kısmını ayıran :- sembolü if anlamına gelir. Örneğin Pascal daki if komutu, öncelikle if komutundan sonra gelen ifadenin doğru olup olmadığını kontrol eder. Eğer ifade doğrulanırsa, komut then ifadesinden sonraya geçer geçer. Yani if x>10 then writeln( Bu iģlem tamam ); satırında öncelikle x değiģkeninin 10 dan büyük olup olmadığı kontrol edilir. Eğer sonuç doğru ise Bu iģlem tamam satırı görüntülenir. Aksi takdirde program bir alt satırdan itibaren çalıģmaya devam eder. Bu tip ifadeye if/then Ģartlı denir. VIP ise bunun tam tersi olan bir sistem uygular. Öncelikle gövdedeki alt hedeflerin doğru olup olmadığına bakılır. Tamamı olumlu sonuç verirse, kuralın gövde kısmının doğruluğu ispatlanmıģ olur. Bu ise VIP da then/if Ģartının geçerli olduğunu gösterir Otomatik Tip Dönüştürmeler VIP de iki değiģken karģılaģtırıldığında her ikisinin de aynı tipte olması her zaman gerekmez. DeğiĢkenler bazen baģka tiplerdeki sabit değiģkenlere de atanabilir. Çünkü VIP aģağıdaki tipler arasında otomatik olarak tip dönüģtürmesini yapar. * string ve symbol * Bütün integral tipler ve reel değiģkenler. Bir karakter sayısal bir değere dönüģtürülürken, bu karakterin karģılığı, sayının ASCII tablosundaki karģılığı olur. Örneğin string tipindeki bir agüman symbol tipi ile uyumludur. Benzer Ģekilde integer olarak tanımlı bir tip real, char, word etc. Tipleriyle uyumludur. Bu tür tip değiģikliği Ģu kolaylıkları sağlar: string tipiyle tanımlı bir yüklem symbol tipindeki bir argümanla çağrılabilir. real tipiyle tanımlı bir yüklem integer tipindeki bir argümanla çağrılabilir. char tipiyle tanımlı bir yüklem integer tipindeki bir argümanla çağrılabilir. Alfabetik karakterler ASCII değerleri bilinmeden de rahatlıkla kullanılabilir. 30

41 Argümanlar, tanımlı olduklarının dıģında bir tipe dönüģürken ne gibi kuralların etkili olduğu, sonuçta ortaya çıkan argümanının hangi tipte olacağı konusu ileride incelenecektir Bir Programın Diğer Bölümleri ġimdiye kadar VIP daki clauses, predicates, domains ve goals bölümleri incelenmiģ ve bol miktarda örnek verilmiģtir. ġimdi database, constants ve global bölümlerine kısa bir giriģ yapılacaktır Database Bölümü Bir VIP programının gerçekler ve kurallardan oluģtuğu bilinmektedir. Program çalıģırken bazen kullanılan gerçek ve kuralları değiģtirmek, güncellemek, ilave yapmak veya çıkarmak gerekebilir. Böyle bir durumda gerçekler, dinamik bir dahili veritabanı oluģturur. Program çalıģırken değiģtirilebilecek gerçeklerin tanımlı olduğu bölüme database bölümü denilmektedir Constants Bölümü Diğer dillerde olduğu gibi VIP de de sabit değiģkenler kullanılabilir. Bu değiģkenler constants bölümünde tanımlanır. Her bir satıra sadece tek bir sabit yazılabilir. constants yuz=(10*(10-1)+10) pi= maas_katsayisi=4 mavi=5 Program derlenmeden önce her sabit değiģkenin karģısındaki string olduğu gibi atanır. Örnek: A=yuz*34, bekle(a) Ģeklindeki A değiģkenine yuz sabiti yerine 100 değil, yuz sabit değiģkeninde tanımlı Ģekliyle (10*(10-1)+10) değeri atanır. Sembolik sabitlerin yazımında Ģu kurallar geçerlidir: 31

42 * Sabit bir değiģken kendisini çağıramaz. Yani sayi= 2*sayi/2 yanlıģtır. * Büyük veya küçük harfle baģlayan sabit değiģkenler, farklı olarak iģlem görmezler. Bu yüzden büyük harfle baģlayan sabit bir değiģken clause veya goal bölümünde küçük harfle baģlatılmalıdır. Böylece büyük harfle baģlamaları zorunlu olan normal değiģkenlerle karıģmazlar. Örnek: constants iki=2 goal A=iki, write(a). Bir programda birden fazla constants bölümü olabilir. Fakat programda kullanılmadan önce bu değiģkenlerin mutlaka tanımlanmıģ olmaları gerekir. Tanımlanan sabitler tanımlanan noktadan baģlayıp programın sonuna kadar aynı değerde kalırlar. Bir sabit değiģken sadece bir kez tanımlanabilir Global Bölümü VIP de Ģimdiye kadar tanımladığımız domains, predicates ve clauses bölümleri tamamen lokal idi. Bunları global yapmak için programın en baģında global domains, global predicates vs. bölümler oluģturulabilir. Bu konu daha sonra incelenecektir Derleyici Direktifleri VIP, yazılan bir program parçasının derleme sırasında belirtilen Ģekilde iģlem görmesi için bazı direktiflerin kullanılmasına imkan tanır. Bu seçenekler menüdeki Options/Compiler Directives baģlığından ayarlanabilir Include Direktifi Bu direktif daha önce yazılan bir program parçasının veya prosedürün her çağrıldığında aynı program içerisinde tekrar tekrar kullanılmasını sağlar. Bu durum basit bir örnek üzerinde açıklanmaktadır. Ġçinde en sık kullanılan tip ve yüklemlerin bulunduğu TEST.PRO isminde bir programın olduğunu varsayalım. Hazırlanan baģka bir programda bu program çağırılıp kullanılmak istendiğinde, kullanılan 32

43 include test.pro bir derleyici direktifidir. Ana program derlendiği zaman VIP test.pro isimli programı derleyip ana programa ilave eder. Include direktifiyle tanımlanan bir programda da baģka bir include satırı bulunabilir ve o da baģka bir programı çağırabilir. Fakat bir programda bir dosya sadece bir kez include dosyaismi.pro Ģeklinde kullanılabilir Bölüm Özeti 1. Bir VIP programının yapısı Ģu Ģekildedir: domains argüman1,...,argümann=tip predicates yüklem_ismi(argüman1,..., argümann) clauses kurallar ve gerçekler GOAL alt_hedef1, alt_hedef2,..., alt_hedefn 2. Domains bölümünde kullanılacak değiģkenlerin tipleri tanımlanır. VIP da kullanılabilecek bazı tipler: char, byte, short, ushort, word, integer vs. 3. YazılmıĢ olan gerçek ve kuralları inceleyerek doğruluğunun sağlanması istenilen Goal (sorgu), programın içine yazılması gerekir. Bu dahili bir sorgudur. Harici olarak tanımlanacak olan bir sorgu program çalıģırken açılan Dialog penceresine yazılır. 4. Aynı isimde fakat farklı sayıda argüman taģıyan yüklemler tamamen farklı yüklemlermiģ gibi iģlem görür. 5. Kurallar BaĢ:- alt_hedef1, alt_hedef2,..., alt_hedefn genel Ģekliyle yazılır. Bir kuralın istenilen sonucu vermesi için alt hedeflerin tamamının doğrulanması gerekir. 6. Prolog daki if komutu diğer dillerdeki if komutundan farklıdır. Prolog da then/if Ģeklinde tanımlı olan bu komut diğer dillerde if/then Ģeklinde tanımlıdır. 33

44 4. EŞLEŞTİRME VE GERİYE İZ SÜRME VIP bir alt hedeften gelen bir çağrıyı clauses bölümünde tanımlı bir cümle ile karģılaģtırmaya çalıģırken belirli bir iģlem kullanır. Bu iģleme eģleģtirme denir. Bir program çalıģırken Goal yazdi(x,y). sorgusunun kullanıldığını kabul edilsin. Bu sorgunun doğruluğunu araģtırırken, clauses bölümdeki bütün yazdi(x,y) cümlecikleri eģleģtirme iģlemi için test edilir. Goal yazdi(x,y) ifadesindeki X ve Y argümanları, clauses bölümündeki yazdi(...) cümlecikleriden kontrol edilir. Bunun için bütün cümlecikler tek tek incelenir. Sorguyla eģleģen bir cümle bulunduğu zaman cümledeki değer serbest olan değiģkene atanır ve böylece cümle ile goal eģleģmiģ olur. Bu duruma sorgunun cümle ile eģleģmesi, bu iģleme de eģleģtirme denilir. Örnek DOMAINS kitap_adi, yazar = symbol sayfa_sayisi = unsigned PREDICATES kitap(kitap_adi, sayfa_sayisi) nondeterm yazdi(yazar, kitap_adi) nondeterm roman(kitap_adi) CLAUSES yazdi(eco, "Gülün Adı"). yazdi(tolstoy, "Ġnsan Ne Ġle YaĢar"). kitap("ġnsan Ne Ġle YaĢar ", 245). kitap("gülün Adı", 760). roman(kitap_adi):- yazdi(_, Kitap_adi), kitap(kitap_adi, Sayfa_sayisi), Sayfa_sayisi> 400. GOAL yazdi(yazar, Kitap_adi). Sorgudaki Yazar ve Kitap_adi değiģkenleri serbest değiģkenler olduklarından herhangi bir argümana eģitlenebilirler. Dolayısıyla sorgu clauses bölümündeki ilk yazdi 34

45 cümlesi ile eģleģir. Yani yazdi(yazar, Kitap_adi) cümleciği yazdi(eco, Gülün Adı ) olur. Burada Yazar=eco, Kitap_adi=Gülün Adı değerini alır. Aynı iģlem bütün alternatif çözümler için tekrar edileceğinden, Yazar ve Kitap_adi değiģkenleri sırasıyla tolstoy ve Ġnsan Ne Ġle YaĢar değerlerini de alır. Yani sonuçta 2 çözüm bulunur. GOAL roman(roman_adi) çağrısının nasıl çalıģtığı incelenecektir. Bir çağrının bir olgu veya kuralın baģ kısmıyla eģleģip eģleģmediği kontrol edilir. Yani kuralın baģ kısmı olan roman(kitap_adi) kısmıyla eģleģir. Kullanılan olgudaki argümanlar eģleģtirilir. X argümanı bağlı olmadığı için herhangi bir argümanla eģleģebilir. Kuralın baģı olan roman(kitap_adi) ında, Kitap_adi argümanı bağımsız bir değiģkendir. Kuralın baģıyla sorgu kısmı eģleģtirilir. VIP, eģleģtirme yapıldıktan sonra alt hedefleri sırasıyla doğrulamaya çalıģır. roman(kitap_adi):- yazdi(_, Kitap_adi), kitap(kitap_adi, Sayfa), Sayfa>400. GOAL roman(roman_adi) kodunda ilk önce yazdi(_,kitap_adi) kısmı sorgulanır. Buradaki ilk argüman anonimdir. Dolayısıyla ilk olgudaki eco ve Gülün Adı _ ve Kitap_adi argümanlarıyla eģleģir. Bundan sonra kitap(kitap_adi,sayfa_sayisi) cümleciğindeki kitap olgusuna çağrı yapılır. Ġlk cümlecikteki eco ve Gülün Adı değerlerini alır. Ġlk alt hedef doğrulandığı için sonraki adım olarak kitap(kitap_adi, Sayfa_sayisi) alt hedefine geçilir. Kitap_adi argümanı Gülün Adı değerine bağlı hale geldiği için çağrı kitap( Gülün Adı, Sayfa_sayisi) Ģeklinde devam eder. Programın baģından baģlayan sorgu kitap( Gülün Adı, 760) cümleciğinde eģleģtirme yapmaz. Çünkü ilk argüman Gülün Adı olmuģtu. Ġkinci cümlecik sorguyu doğrular ve Sayfa_sayisi 760 değerini alır. Sayfa_sayisi>400 alt hedef halini alır. 760 değeri 400 den büyük olduğu için alt hedef doğrulanır ve böylece bütün hedef doğrulanmıģ olur. Sonuçta Ģu mesaj görüntülenir: Roman_adi=Gülün Adı 1 Solution 35

46 4.1. Geriye İz Sürme Gerçek problemlere çözüm ararken, verilen karar doğrultusunda mantıklı olan bir yol takip eder, yolun sonuca ulaģmaması durumunda alternatif bir yol aranır. Mesela bir labirent oyununda çıkıģ yolunu ararken sola veya sağa doğru gidilir. Çıkmaz sokağa gelindiğinde geriye döner, baģka bir yolu takip eder. Bu yönteme göre devam edilirse, sonunda çıkıģ noktası bulunur. VP, geriye iz sürme denilen bu sistemi kullanır. Bir sorgunun doğru olup olmadığı araģtırılırken alt hedeflerin herbirinin ayrı ayrı doğrulanmaya çalıģılır. VP, doğrulama iģlemini yürütürken sorgulanması gereken durumların baģlangıç noktasına bir iģaret koyar. Sonra bu yolların ilkini dener. Eğer olumlu sonuç alınırsa iģleme oradan itibaren devam eder. Sonucun olumsuz çıkması durumunda, iģaret konulan yere döner ve ikinci yolu, yani bir sonraki alt hedefi dener. ĠĢte bu ileriye gidiģ ve gerektiğinde yine geriye dönüģ iģlemine Geriye İz Sürme denir. Örnek PREDICATES nondeterm yemeyi_sever(symbol, symbol) nondeterm yemek(symbol) yemegin_tadi(symbol, symbol) CLAUSES yemeyi_sever(besir,x):- yemek(x), yemegin_tadi(x, iyi). yemegin_tadi(kebap, iyi). yemegin_tadi(kapuska, kotu). yemek(kapuska). yemek(kebap). GOAL yemeyi_sever(besir, Besirin_Sevdigi_Yemek). Programda iki olgu kümesi, bir de kural bulunmaktadır. Kural, Bülent in, tadı güzel olan yemeklerden hoģlandığını söylemektedir. Sorgunun doğrulanması için VP ilk satırdan baģlayarak tarama yapar. Hedefe uyan ilk satır yemeyi_sever(bulent, X) kuralının baģı olduğu için Besirin_Sevdigi_Yemek argümanı X ile eģleģir. Bu durumda 36

47 kuralın geri kalan kısmının doğrulanmasına çalıģılır. Buradaki ilk alt hedef yemek(x) cümleciğidir. VP alt hedefi doğrulamak için yine programın en baģına gider. VP eģleģen bir olgu ararken yemek(kapuska) cümleciğine ulaģır ve burada X değiģkeni kapuska değerini alır. VIP, buraya geri dönüģ iģaretini koyar ve alternatif bir çözüm ararken hareket edilecek ilk noktanın baģlangıcı belirtilmiģ olur. Bir sonraki hedef, yemegin_tadi(x, iyi) alt hedefi olur. X kapuska değerini aldığına göre bu cümle yemegin_tadi(lahana, iyi) Ģekline dönüģür. Bunun doğrulanması sırasında argümanlar baģka bir olguyla eģleģmediği için bu alt hedef olumsuz olur. Dolayısıyla sorgunun bu doğrulanması baģarısız olur. ĠĢte bu noktada VP geri dönüģ iģaretini koyduğu en son noktaya, yani yemek(kapuska) cümleciğine gider. Geri dönüģ noktasına gelindiğinde, bu noktadan sonra değer almıģ olan bütün değiģkenler yeniden serbest hale gelirler. Bu noktadan sonra ilk eģleģme yemek(kebap) olgusu ile olur ve X değiģkeni kebap değerini alır. Daha sonraki alt hedef yemegin_tadi(kebap, iyi) olduğundan, programın baģından itibaren yapılacak bir taramadan olumlu sonuç alınır. Çünkü yemegin_tadi(kebap, iyi) olgusu önceden tanımlanmıģtı. Sonuçta görüntülenecek mesaj Ģu olur: Besirin_sevdigi_yemek=kebap 1 Solution Geriye Ġz Sürme yöntemiyle sadece tek çözüm değil, mümkün olan bütün çözümler elde edilir. DOMAINS aday=symbol adayin_yasi=integer PREDICATES nondeterm oyuncu(aday, adayin_yasi) CLAUSES oyuncu(ahmet, 10). oyuncu(mehmet, 12). oyuncu(ali, 10). oyuncu(huseyin, 10). 37

48 GOAL oyuncu(birinci_oyuncu, 10), oyuncu(ikinci_oyuncu, 10), Birinci_oyuncu<>Ikinci_oyuncu. VP den yaģları 10 olan çocuklar arasında düzenlenecek bir masa tenisi turnuvası için muhtemel ikili rakip listesi istensin. EĢleĢtirme sırasında yaģları 10 olan, fakat kendileriyle eģleģmeyecek ikili gruplar istensin. Geriye Ġz Sürme yönteminin nasıl çalıģtığını görmek için VP nin takip edeceği prosedürü adım adım yazarsak: 1. VP ilk önce sorgunun oyuncu(birinci_oyuncu, 10) alt hedefini doğrulamaya çalıģır. Bu hedef oyuncu(ahmet, 10) cümleciğiyle sağlanmıģ olur. VP hemen ikinci alt hedefi doğrulamaya çalıģır. (Bu sırada programın en baģına dönüģ yapılır) oyuncu(ġkinci_oyuncu, 10) alt hedefini sağlamaya çalıģırken yine 10 yaģ Ģartını birinci cümlecik sağlar. Dolayısıyla Ġkinci_oyuncu argümanı da ahmet değerini alır. Her iki alt hedef sağlandıktan sonra Ģimdi üçüncü alt hedef sağlanmaya çalıģılır. Yani Birinci_oyuncu<>Ġkinci_oyuncu (Birinci ve ikinci oyuncu aynı kiģi olmayacak) 2. Oyuncuların her ikisi de ahmet olarak eģleģtiği için bu hedef sağlanamaz, dolayısıyla sorgu baģarısız olur. VP nin Geriye Ġz Sürme mekanizması yeniden bir önceki alt hedefi, yani ikinci alt hedefi sağlamaya yönelir. Bu kez ikinci_oyuncu argümanı ali değerini alır. 3. Üçüncü alt hedef sağlanmıģ olur. Çünkü ahmet ve ali, yaģları 10 olan farklı kiģilerdir. Bütün alt hedefler sağlandığından sorgunun tamamı baģarılmıģ olur. Sonuçta oluģan ilk ikili Birinci_oyuncu= ahmet, Ġkinci_oyuncu=ali olarak bulunmuģ olur. 4. VP nin sadece bir çözüm değil, mümkün olan bütün çözümleri bulur. Bu yüzden 3. alt hedef sağlandıktan sonra baģka çözüm olup olmadığını bulmak için bütün alternatifler tükeninceye kadar ikinci alt hedefi sorgulanır. Bu kez ikinci_oyuncu olarak Hüseyin seçilir. Ahmet ve Hüseyin 3. Ģartı da sağladığı için ikinci grup ahmet ve hüseyin den oluģur. 5. Peki baģka çözüm var mı? VP bunu bulmak için yine ikinci alt hedefe dönüģ yapar. Görüldüğü gibi son oyuncu olan Hüseyin ile bu ĢanĢ tükenmiģtir. ĠĢte bu noktada Geriye Ġz Sürme yine ilk alt hedefe döner. Ġkinci eģleģme oyuncu(ali, 10) 38

49 cümlesinde olur. Ġkinci oyuncu Hüseyin ile eģleģir. En son alt hedef de sağlandığı için bu kez ali=hüseyin ikilisi oluģturulur. 6. BaĢka çözüm için VP 2. alt hedefe döner. VP ikinci kez hüseyin ismiyle eģleģme yapar. Fakat kiģi aynı olduğundan sonuç alınamaz. Geriye Ġz Sürme yöntemiyle bütün seçeneklerin sırasıyla denenmesi sonucunda Ģu tablo ortaya çıkar. Birinci_oyuncu=ahmet, Ġkinci_oyuncu=ali Birinci_oyuncu=ahmet, Ġkinci_oyuncu=hüseyin Birinci_oyuncu=ali, Ġkinci_oyuncu=ahmet Birinci_oyuncu=ali, Ġkinci_oyuncu=hüseyin Birinci_oyuncu=hüseyin, Ġkinci_oyuncu=ahmet Birinci_oyuncu=hüseyin, Ġkinci_oyuncu=ali 6 Solutions Bulunan sonuçların bazıları, isimlerin sadece yer değiģtirilmesinden oluģmuģ aynı ikili gruplardır. Bunu engellemek mümkündür. (Not: Aynı program ile yaģları 10 ve 12 olan ikili grupları bulunuz) 4.2. Geriye İz Sürme Mekanizmasının Ayrıntıları AĢağıdaki programa bakarak Geriye Ġz Sürme iģlemenin nasıl iģlediğini anlamaya çalıģalım. DOMAINS isim, sey= symbol PREDICATES sever(isim, sey) okur(isim) merakli(isim) CLAUSES sever(ahmet, limonata):-!. sever(murat, yuzme):-!. sever(murat, kitap):-!. sever(murat, basketbol):-!. sever(z,kitap):- 39

50 okur(z), merakli(z). okur(ahmet). merakli(ahmet). GOAL sever(x, limonata), sever(x, kitap). VP hedefi değerlendirirken, doğrulanan ve doğrulanamayan alt hedefleri belirler. Yukarıdaki programa aģağıdaki hedefi göz önüne alarak bakalım. Hedef aģağıdaki gibi bir ağaç dalı Ģeklinde gösterilebilir. Doğrulanan alt hedefi altı çizili halde, bununla eģleģen cümleciği de bunun hemen altına yazalım. sever(x,limonata) Sever(X,kitap) Geriye İz Sürmenin 4 Temel Prensibi Yukarıdaki örnekte, hedefin gerçekleģtirilmesi için doğrulanması gereken iki alt hedef vardır. Bunun için VP dört temel prensibe göre çalıģır: 1. Bütün alt hedefler, ilkinden baģlanmak üzere, birer birer doğrulanmalıdır. Bir cümleciğin doğrulanması için hangi alt hedefin kullanılacağına ikinci kurala göre karar verilir. 2. Yüklem cümlecikleri (fonksiyonlar) programdaki sırasıyla, yukarıdan aģağıya göre test edilirler. Buna göre yukarıdaki program çalıģırken sever yüklemini sağlayan sever(ahmet, limonata) cümleciğiyle doğrulanır. Dolayısıyla sever(x, limonata) alt hedefindeki X argümanı ahmet değerini alır. Daha sonra ikinci alt hedef doğrulanmaya çalıģılır. Burada bağlı hale gelen X=ahmet argümanı kullanılır. Fakat sever(ahmet, limonata) alt hedefi sever(ahmet, kitap) alt hedefine eģitlenemez, çünkü limonata ve kitap aynı değildir. Bütün cümleciklerin sırayla deneneceği için bir sonraki cümlecik sever(murat, kitap) olacaktır. Fakat X daha önce ahmet değerini aldığı için bu Ģık da baģarısız olur. Bu yüzden bir sonraki sever cümleciğinin sağlanması gerekir. sever(z,kitap):-okur(z), merakli(z). Z argümanı bir değiģkendir ve X değiģkeni ile eģleģebilir. Zaten kitap argümanları da eģleģir. Dolayısıyla hedef, kuralın baģ kısmıyla eģleģmiģ olur. Bir alt hedef bir kuralın baģ kısmıyla eģleģtiği zaman, kuralın gövde kısmının doğrulanması sağlanmalıdır. Böylece kuralın gövdesi doğrulanması gereken bir alt hedefler kümesi oluģturur. 40

51 ġimdi yeniden örneğe dönelim. sever(x,limonata) sever(x,kitap) okur(z) merakli(z) okur(z) ve merakli(z) alt hedeflerinin doğrulanması gerekir. Burada Z değiģkeninin ahmet değerini aldığı söylenmiģti. ġimdi ise her iki alt hedefi de sağlayan sorgulama baģlayacaktır. Sonuçta elde edilecek ağaç: sever(x,wine) sever(x,kitap) sever(ahmet,wine) sever(z,kitap) okur(z) merakli(z) okur(ahmet) merakli(ahmet) 4. Hedef ağacının her bir dalını sağlayan bir gerçek bulunduğu zaman hedef sağlanmıģ olur. Sonuçta X=ahmet 1 Solution cevabı görüntülenir. Harici bir hedef doğrulandıktan sonra VP nin, eğer varsa, bütün alternatifleri bulmak için çalıģacağı söylenmiģti. Bir alt hedef baģarısız olursa, VP yeniden bir önceki alt hedefe döner. Bu alt hedefi, biraz önce baģarısız hale gelen alt hedefi de doğrulayacak bir cümlecik ile doğrulamaya çalıģır. VP bir alt hedefi sağlamak için sorgulamaya yüklemi tanımlayan ilk cümlecikten baģlar. Bu sırada aģağıdaki durumlardan biri meydana gelebilir: 1. Ġlk cümlecik verilen yüklemle eģleģir. Bu durumda; a. Alt hedefi doğrulama ihtimali olan baģka bir cümlecik varsa, Geriye Ġz Sürme iģleminde kullanılmak üzere bu cümleciğin yanına bir iģaret konur. b. Alt hedefteki bütün serbest değiģkenler cümlecikteki değerleri alır ve bağlı hale gelirler. c. Eğer eģleģen cümlecik bir kuralın baģ tarafı ise, hemen kuralın gövde kısmı değerlendirilir. Bu durumda gövdedeki bütün alt hedeflerin doğrulanması gerekir. 2. EĢleĢen herhangi bir cümlecik bulunmaz ve sorgu baģarısız hale gelir. VP bir önceki alt hedefi doğrulamak için geriye iz sürer. En son geriye dönüģ noktasına geldiğinde, VP geriye dönüģ noktasından sonra değer almıģ bütün değiģkenleri serbest hale getirir. Daha sonra alt hedefi yeniden doğrulamaya çalıģır. 41

52 Tarama, programın baģından baģlar. Geriye Ġz Sürme iģlemi, daha önce yerleģtirilen geriye dönüģ noktasından itibaren baģlar. Sorgu burada da baģarısız olursa, geriye iz sürme iģlemi tekrar edilir. Bütün alt hedef ve cümlecikler için geriye dönüģ iģlemi tamamlandığında sonuç elde edilemezse, hedef baģarısız olur. Geriye dönüģ iģlemi için baģka bir örnek. Örnek: PREDICATES nondeterm tur(symbol, symbol) nondeterm canli(symbol, symbol) yasar(symbol, symbol) nondeterm yuzebilir(symbol) CLAUSES tur(tirnakli, hayvan). tur(balik, hayvan) canli(zebra, tirnakli). canli(alabalik, balik). canli(kopekbaligi, balik). yasar(zebra, karada). yasar(kurbaga, karada). yasar(kurbaga, suda). yasar(kopekbaligi, suda). yuzebilir(y):- tur(x, hayvan), canli(y,x), yasar(y, suda). GOAL yuzebilir(ne), write( Bir ",Ne," yüzebilir\n"). Program yazılıp çalıģtırıldığında ilk olarak GOAL bölümü sağlanmaya çalıģılır. ġimdi yapılacak iģlemleri adım adım yazalım: 1. yuzebilir yüklemi, Ne serbest değiģkeni ile çağrılır. EĢleĢme olup olmadığını bulmak için program tarandığında Ne argümanı Y değerini alır. 42

53 2. Hemen sonra hedefin gövde kısmına geçersek tur(x,hayvan) alt hedefinin doğrulanması gerekir. Programın baģından itibaren yapılacak bir taramada tur(tirnakli, hayvan) cümleciği bu alt hedefi sağlar. Böylece X=tirnakli değerini alır. 3. Burada tur(x,hayvan) alt hedefini sağlayabilecek birden fazla alternatif olduğu için, tur(tirnakli,hayvan) cümleciğinin yanına Geriye Ġz Sürme iģareti konur. 4. X değiģkeni tirnakli değerini alınca birinci alt hedef doğrulanmıģ olur. Bu kez ikinci alt hedef yani canli(y, X) doğrulanmaya çalıģılır. Bu hedef ise canli(y, tirnakli) olarak sağlanır. canli(zebra, tirnakli) cümleciği ikinci alt hedefi sağlar ve Y değiģkeni zebra değerini alır ve bu hedefi sağlayan baģka cümlecikler de mevcut olduğundan, VP bu cümleciğin yanına da bir Geriye Ġz Sürme iģareti koyar. 5. ġimdi X=tirnakli ve Y=zebra olacak Ģekilde en son alt hedefin doğrulanması gerekir. yasar(y, suda) alt hedefinin sağlanması için yasar cümleciklerinin biriyle eģleģmesi gerekir. Fakat cümlecikler arasından bunu sağlayan bir gerçek olmadığı için hedef baģarısız olur. 6. VP bu noktada geriye dönüģ iģareti koyduğu en son noktaya, yani ikinci alt hedef ve canli(zebra, tirnakli) cümleciğine döner. 7. Geriye dönüģ noktasına geldiğinde, bu noktadan sonra değer almıģ bütün değiģkenler serbest hale gelir. Daha sonra canli(y, tirnakli) alt hedefine yeni bir çözüm arar. 8. VP daha önce iģaret koyup durduğu satırdan baģlamak üzere, geriye kalan cümlecikler arasında tarama yaparak Ģimdiki alt hedefe uyacak bir çözüm arar. Programımızda alt hedefi doğrulayacak baģka bir seçenek bulunmadığından, yapılan çağrı baģarısız olur ve VP yeniden bir önceki alt hedefe döner. 9. Bu kez tur(tirnakli, hayvan) hedefini doğrulamaya çalıģır. Çünkü geriye dönüģ iģareti buraya konulmuģtu. 10. Bütün değiģkenler serbest hale getirilir ve yeniden tur(x, hayvan) alt hedefine çözüm arar. Geriye dönüģ noktasından sonraki tur(balik, hayvan) cümleciği bu hedefi doğrular ve X=balik değerini alır. VP bu kez geriye dönüģ noktasını bu cümleciğin yanına yerleģtirir. 43

54 11. VP Ģimdi kuraldaki ikinci alt hedefi doğrulamak üzere aģağıya doğru hareket eder. Bu tarama yeni bir tarama olduğu için tarama yine cümleciklerin baģından, yani canli(y, tirnakli) cümleciğinden baģlar. 12. canli(alabalik, balik) cümleciği alt hedefi doğrular ve Y=alabalik değerini alır. 13. Y Ģimdi alabalik değerini aldığı için, yasar(alabalik, suda) alt hedefi çağrılır. Bu da yeni bir çağrı olduğu için program yine baģtan baģlar. 14. Cümleciklerde görüldüğü gibi, yasar yüklemleri arasında yasar(alabalik, suda) alt hedefini doğrulayacak bir seçenek yoktur. Bu yüzden çağrı baģarısız olur ve bir önceki alt hedefe yeniden dönüģ yapılır. 15. canli(alabalik, balik) geriye dönüģ noktasına gidilir. 16. Bu noktadan sonra değer alın bütün değiģkenler yeniden serbest hale geldikten sonra canli(y, balik) çağrısına cevap aranır. 17. Bu kez Y=kopekbaligi değeri alt hedefi sağlar. 18. VP üçüncü alt hedefi yeniden doğrulamaya çalıģır. Y kopekbaligi değerini aldığı için yasar(kopekbaligi, suda) alt hedefinin doğrulanması gerekir. Bu yeni çağrı doğrulanır, çünkü son cümlecik eģleģmektedir. 19. Alt hedeflerin doğrulanmasından sonra kuralın baģ kısmı da sağlanmıģ olur. VP, Y değiģkeninin aldığı kopekbaligi değerini yuzebilir(ne) kuralındaki Ne değiģkenine atar ve böylece Goal bölümündeki write("bir ",Ne," yüzebilir\n") alt hedefi de çağrılır. Sonuç: Bir köpekbalığı yüzebilir Ne=kopekbaligi 1 Solution 4.3. Tarama İşleminin Kontrol Edilmesi VP de var olan geriye iz sürme mekanizması bazen gereğinden fazla tarama yapabilir. Bu ise verimi düģürür. Bazen verilen bir problem için sadece bir çözüm bulmak istenebilir. Bazen de, bir çözüm bulunsa bile varsa- baģka alternatif çözümleri de bulmak istenebilir. ĠĢte bu gibi durumlarda geriye dönüģ iģleminin kontrol edilmesi gerekir. 44

55 Geriye Ġz Sürme iģlemini kontrol edebilmek için VP nin iki özelliğinden faydalanılabilir. Bunlar,: VP yi geriye iz sürme iģlemi yapmaya zorlayan fail yüklemi ve geriye dönüģ mekanizmasını engelleyen cut! özelliğidir fail Yükleminin Kullanılması Alt hedeflerden birinin sağlanamaması durumunda geriye dönüģ iģlemi yapılır. Bazı durumlarda alternatif çözümleri bulabilmek için bu iģlemin yapılması gereklidir. VP nin fail yüklemi, bir sorgunun baģarısız olmasına ve böylece geriye dönüģ iģleminin yapılmasına imkan tanır. DOMAINS isim=symbol PREDICATES nondeterm baba(isim, isim) herkesi_bul CLAUSES baba("ömer ", yavuz). baba(ahmet, kasim). Baba(huseyin, veli). Baba(murat, yusuf). herkesi_bul:- baba(x,y), write(x, Y," Babası\n"), fail. herkesi_bul. GOAL herkesi_bul. Programdaki dahili hedef doğrulandıktan sonra VP nin geriye iz sürmesine gerek yoktur. Bundan dolayı baba iliģkisine yapılan ilk çağrı baģarılı olur ve sadece bir tek çözüm sağlanmıģ olur. Fakat yüklem bölümündeki herkesi_bul yüklemi fail özelliğini kullanarak Prologu geriye iz sürme mekanizmasını kullanmaya zorlar ve mümkün olan bütün çözümlerin bulunmasını sağlar. Herkes yükleminin amacı, görüntülenen cevapların daha net olmasıdır. 45

56 Herkes yüklemi VP yi zorlayarak, baba(x,y) kuralının sağlanması için geriye dönüģ iģleminin çalıģtırılmasını sağlar. Daima olumsuz cevap vereceği için fail kuralının doğrulanması mümkün değildir. Bu yüzden VP daima bir üstteki alt hedefe geriye dönüģ yapar. Geriye dönüģ olduğunda VP, birden fazla çözüm verebilecek en son hedefe döner. Bu tür bir çağrı belirsiz (non-deterministic) olarak tanımlanır. Belirsiz bir çağrı, belirli olan ve sadece bir tek çözüm sunabilen bir çağrının tam tersidir. write yükleminin doğruluğu yeniden sağlanamaz, çünkü yeni çözümler sunmaz. Haliyle VP kuraldaki ilk alt hedefe geriye dönüģ yapar. fail yüklemini takiben baģka alt hedeflerin yazılması hiçbir iģe yaramaz. Çünkü fail yükleminin kendisi daima baģarısız olacağından, fail yüklemini takip eden bir alt hedefin sorgulaması mümkün değildir Geriye İz Sürmeyi Engelleme VP de ünlem iģareti ile gösterilen (!) cut yükleminden itibaren geriye dönüģ mümkün değildir. Cut yüklemi, bir kuralın içinde herhangi bir alt hedefmiģ gibi yazılır. Program çalıģırken cut alt hedefi daima doğrulanır ve iģlem bir alt hedefe geçer. Bu hedeften önceki alt hedeflere ve cut komutunu içeren alt hedefin kendisine geriye dönüģ artık mümkün değildir. Cut komutu iki amaç için kullanılır: 1. Alternatif çözümün mümkün olmadığına önceden karar verilirse, vakit ve bellek kaybını önlemek için bu komut kullanılabilir. Böylece program daha hızlı çalıģır. Buna green cut (Olumlu Cut) denir. 2. Programın kendi mantığı cut yüklemini gerektiriyorsa, alternatif alt hedeflerin incelenmesini önlemek için de cut kullanılır. Buna ise red cut (Olumsuz Işık) adı verilmektedir Cut Komutunun Kullanımı Bu bölümde cut komutunun kullanımı ile ilgili örnekler üzerinde çalıģalım. r1, r2, r3 kuralları r yüklemini, a, b, c ise alt hedefleri gösterir. Bir kural içindeki bir alt hedefe geri dönüģü engellemek için R1:- a, b,!, c. yazılabilir. 46

57 Yukarıdaki kuralın anlamı Ģudur: Kural içerisindeki a ve b alt hedeflerini doğrulayan bir çözüm bulunduğunda programı durdur. Bu yüzden cut komutunu geçip c alt hedefine geçmek mümkün değildir. Dolayısıyla a ve b için alternatif çözümler mümkün olsa da, sadece bulunan ilk çözümle yetinilir. Cut komutu r1 yüklemini tanımlayan baģka bir cümlecik içine gitmeyi de engeller. Örnek PREDICATES araba_satin_al(symbol,symbol) nondeterm araba(symbol,symbol,integer) renkler(symbol,symbol) CLAUSES araba_satin_al(model,renk):- araba(model,renk,fiyat), renkler(renk,cazip),!, Fiyat > araba(murat,yesil,25000). araba(mersedes,siyah,24000). araba(bmw,kirmizi,28000). araba(renault,kirmizi,24000). araba(toyota, sari, 30000). renkler(kirmizi,cazip). renkler(siyah,orta). renkler(yesil,berbat). renkler(sari, cazip). GOAL araba_satin_al(bmw, Hangi_renk). Bu örneğin verilmesinin amacı, rengi cazip, fiyatı da uygun olan bir BMW almaktır. Veri tabanında BMW için zaten bir satır vardır. Prolog un yapması gereken tek Ģey, fiyatının verilen Ģarta uyup uymadığını kontrol etmektir. Goal içerisindeki! komutu, BMW için fiyat uygun değilse, baģka bir araba aranmasını engeller. Programı çalıģtırıldığında Hangi_renk=kirmizi 47

58 1 Solution yanıtı alınır Geriye İz Sürmeyi Engelleme Cut komutu, bir yüklem için doğru olan bir cümlenin seçildiğini belirtmek için de kullanılabilir. r(1):-!, a, b, c r(1):-!, d r(1):-!, c r(_):- write ( Cümlelerin tamamı buraya yazılır ). Cut komutu r yüklemini deterministic (belirli) yapar. Dolayısıyla r yüklemi bir tamsayı argümanı ile çağrılır. Yapılan çağrının r(1) olduğunu kabul edelim. Prolog yapılan çağrıya uygun bir eģleģme ararken, r yi tanımlayan bir cümlecik bulur. Birden fazla çözüm mümkün olduğundan, Prolog ilk cümleciğe geri dönüģ noktası iģareti koyarak aģağıda doğru iģleme devam eder ve geri kalan satırlara geçer. Olacak ilk Ģey, cut komutu geçmektir. Böyle yapmak artık baģka bir r cümleciğine geri dönüģü ortadan kaldırır ve geri dönüģ noktası ortadan kalktığı için, programın çalıģma hızı oldukça artar. Bu tür yapının diğer dillerde yazılan Case yapılarına benzediği görülür. Deneme Ģartı, kuralın baģ tarafında yazılır. Yukarıdaki satırları daha anlaģılır yapmak için Ģöyle yazalım: r(x):- X=1,!, a, b, c. r(x):- X=2,!, d. r(x):- X=3,!,c. r(_):-write ( Cümlelerin tamamı buraya yazılır ). Örnek: PREDICATES arkadas(symbol,symbol) kiz(symbol) sever(symbol,symbol) CLAUSES 48

59 arkadas(ahmet,fatma):- kiz(fatma), sever(ahmet,fatma),!. arkadas(ahmet,mehmet):- sever(mehmet,futbol),!. arkadas(ahmet,esra):- kiz(esra). kiz(tuba). kiz(fatma). kiz(esra). sever(mehmet,futbol). sever(ahmet,esra). GOAL arkadas(ahmet,kimin_arkadasi). Program akıģı içerisinde Cut komutu kullanılmazsa, yukarıdaki örnekten iki ayrı sonuç elde edilir. Yani Ahmet hem Mehmet in hem de Esra nın arkadaģıdır. Fakat arkadas iliskisini tanımlayan ilk cümledeki Cut komutu, bu cümlenin doğrulanıp Ahmet in bir arkadaģının bulunması durumunda, artık ikinci bir arkadaģ bulmanın gereksiz olduğunu vurgular. Bu yüzden yukarıdaki Goal için sadece Mehmet in Ahmet in arkadaģı olduğu cevabı görüntülenir Determinism ve Cut Yukarıdaki örnekte arkadas yüklemi Cut kullanılmadan tanımlanmıģ olsaydı, non-deterministic, yani geriye iz sürme iģlemiyle birden fazla çözüm üretmesi mümkün bir yüklem olacaktı. Programların ihtiyaç duyacakları bellek miktarı artacağından, özellikle non-deterministic yüklemler ile çalıģılırken dikkatli olmak gerekir. VIP nondeterministic yüklemleri dahili olarak kontrol etmekle beraber, güvenli bir program yazmak için check_determ derleyici direktifini kullanmak faydalıdır. Eğer check_determ programın hemen ilk satırına yerleģtirilirse, programın çalıģtırılması esnasında non-deterministic yüklemlere gelindiğinde bir uyarı mesajı görüntülenir. Böylece non-deterministic olan bir yüklemin gövde kısmında (body) uygun bir Cut komutu kullanarak yüklemi deterministic hale getirebiliriz Not Yüklemi Genel Not Ortalaması 3.5 olan ve beklemeli olmayan ġeref Öğrencisini bulman program: 49

60 DOMAINS isim= symbol gno= real PREDICATES nondeterm seref_ogrencisi(isim) nondeterm ogrenci(isim, gno) beklemeli(isim) CLAUSES seref_ogrencisi(isim):-ogrenci(isim,gno),gno>=3.5, not(beklemeli(isim)). ogrenci ("Kasım Yenigün", 3.5). ogrenci("ferit DAĞDEVĠREN", 2.8). ogrenci("orhan AYDIN", 3.8). beklemeli("kasım Yenigün"). beklemeli("ferit DAĞDEVĠREN"). GOAL seref_ogrencisi(seref_ogrencisinin_adi_soyadi). Not komutunu kullanırken dikkat edilmesi gereken tek bir kural vardır: Not komutu, sadece alt hedefin doğruluğunun ispatlanamaması durumunda iģlem görür. Serbest değiģkenli bir alt hedef Not içerisinden çağrıldığı zaman, Prolog, Free variables not allowed in not or retractall (Not veya retractall içerisinde serbest değiģkenler kullanılamaz) hata mesajını verecektir. Prolog un bir alt hedefteki serbest değiģkenlere değer ataması için, bu alt hedefin baģka cümlecikle eģleģmesi ve alt hedefin doğrulanması gerekir. Not içeren bir alt hedefteki bağımsız değiģkenleri kullanmanın en doğru yolu anonim değiģkenler (_) kullanmaktır. AĢağıda bu konu ile ilgili yanlıģ ve doğru örnekler verilmiģtir: sever(ahmet, Herhangi_Biri):- /* Herhangi_Biri çıktı argümanıdır */ sever(esra, Herhangi_Biri), not(nefret_eder(ahmet, Herhangi_Biri). Burada Herhangi_Biri, nefret_eder(ahmet, Herhangi_biri) alt hedefinin doğru olmadığı ispatlanmadan önce Herhangi_biri argümanı sever(esra, Herhangi_biri) alt hedefindeki Herhangi_biri argümanına atanmıģ olur. Dolayısıyla yukarıdaki kod tam olarak arzu edildiği gibi çalıģır. Yukarıdaki kısa program 50

61 sever(ahmet, Herhangi_biri):- /* Doğru çalıģmaz */ not(nefret_eder(ahmet, Herhangi_biri), sever(esra, Herhangi_biri). Ģeklinde yazılacak olursa, ilk önce Not ile baģlayan cümlecik çağrılmıģ olur. Not cümleciği içinde serbest değiģken tanımlamak mümkün olmadığı için, Prolog hata mesajı vermiģ olur. Çünkü not(nefret_eder(ahmet, Herhangi_Biri) cümleciğindeki Herhangi_biri argümanı serbest değiģkendir ve hiçbir değeri yoktur. Programdaki Herhangi_biri yerine anonim değiģken olan (_) kullanılsa bile, Prolog yine yanlıģ bir sonuç verecektir. sever(ahmet, Herhangi_biri):- /*Doğru çalıģmaz*/ not(nefret_eder(ahmet, _), sever(esra, Herhangi_biri). Çünkü yukarıdaki cümlelerden anlaģılan Ģudur: Eğer Ahmet in nefret ettiği bir Ģey bilinmiyorsa ve eğer esra Herhangi_biri ni seviyorsa, Ahmet Herhangi_biri ni sever. Anlatılmak istenen Ģey ise Ģudur: Esra nın sevdiği ve Ahmet in de nefret etmediği Herhangi_biri varsa, Ahmet bu Herhangi_biri ni sever. Not yüklemini kullanırken çok dikkatli olmak gerekir. YanlıĢ kullanım, ya hata mesajı alınmasına ya da program içerisinde mantıksız bir yapıya neden olacaktır. Örnek: PREDICATES Nondeterm alisveristen_hoslanir(symbol) Nondeterm kredi_kartina_sahip(symbol, symbol) kredisi_bitmis(symbol, symbol) CLAUSES alisveristen_hoslanir(kim):- kredi_kartina_sahip(kim,kredi_karti),not(kredisi_bitmis(kim,kredi_karti)), write(kim, Kredi_karti, "ile alıģveriģ yapabilir\n"). kredi_kartina_sahip(yavuz, visa). kredi_kartina_sahip(yavuz, diners). kredi_kartina_sahip(ahmet, shell). kredi_kartina_sahip(mehmet, masterkart). 51

62 kredi_kartina_sahip(asaf_bey, akbank). kredisi_bitmis (yavuz, diners). kredisi_bitmis (asaf_bey, masterkart). kredisi_bitmis (yavuz, visa). GOAL alisveristen_hoslanir(kim). Örnek: DOMAINS isim,cinsiyet,meslek,cisim,yardimci,madde = symbol yas=integer PREDICATES nondeterm sahis(isim, yas, cinsiyet, meslek) nondeterm iliskili(isim, isim) ile_oldurdu(isim, cisim) oldurdu(isim) nondeterm katil(isim) sebep(yardimci) uzerinde_leke_var(isim, madde) sahip(isim, cisim) nondeterm birbirine_benzer(cisim, cisim) nondeterm sahip_oldugu_cisim(isim, cisim) nondeterm supheli(isim) /* * * Katil hakkındaki gerçekler * * */ CLAUSES sahis(huseyin,55,m,arastirma_gorevlisi). sahis(yavuz,25,m,futbolcu). sahis(yavuz,25,m,kasap). sahis(ahmet,25,m,yankesici). iliskili(fatma,ahmet). iliskili(fatma,huseyin). iliskili(deniz,ahmet). 52

63 ile_oldurdu(deniz,sopa). oldurdu(deniz). sebep(para). sebep(kiskanclik). sebep(durustluk). uzerinde_leke_var(huseyin, kan). uzerinde_leke_var(deniz, kan). uzerinde_leke_var(yavuz, camur). uzerinde_leke_var(ahmet, cikolata). uzerinde_leke_var(fatma,cikolata). sahip(huseyin,tahta_bacak). sahip(ahmet,tabanca). /* Temel Bilgiler */ birbirine_benzer(tahta_bacak, sopa). birbirine_benzer(demir, sopa). birbirine_benzer(makas, bicak). birbirine_benzer(futbol_sopasi, sopa). sahip_oldugu_cisim(x,futbol_sopasi):-sahis(x,_,_,futbolcu). sahip_oldugu_cisim(x,makas):-sahis(x,_,_,kuafor). sahip_oldugu_cisim(x,cisim):-sahip(x,cisim). /* Susan'ın oldürüldüğü silaha sahip herkesi Ģüpheli kabul edilsin */ supheli(x):- ile_oldurdu(deniz,silah), birbirine_benzer(cisim,silah), sahip_oldugu_cisim(x,cisim). /* Susan ile iliģkisi olan insanlar da Ģüpheliler listesine girmeli */ supheli(x):- sebep(kiskanclik), sahis(x,_,m,_), iliskili(deniz,x). /* Susan'ın, iliģkilerinden haberdar olduğu bayanlar da Ģüpheli listemizde olmalı */ 53

64 supheli(x):- sebep(kiskanclik), sahis(x,_,f,_), iliskili(x,erkek), iliskili(deniz,erkek). /* ġüpheli, para için katil olan bir yankesici olabilir */ supheli(x):- sebep(para), sahis(x,_,_,yankesici). katil(katil):- sahis(katil,_,_,_), oldurdu(olduruldu), Olduruldu <> Katil, /* It is not a suicide */ supheli(katil), uzerinde_leke_var(katil,devam), uzerinde_leke_var(olduruldu,devam). GOAL katil(katil_kim) Prosedürel Açıdan Prolog Prolog tanımsal yapıya sahip bir dildir. Program hazırlarken problem olgular(önceden bilinen gerçekler) ve kurallarla tanımlanır. Bunu takiben bilgisayardan çözüm bulması beklenir. Pascal, BASIC ve C gibi diller ise tamamen prosedürlere dayanırlar. Bilgisayarın belli bir probleme çözüm bulabilmesi için, programcının, yapılması gereken iģlemleri alt programlar ve fonksiyonlar halinde adım adım tanımlaması gerekir Kurallar ve Olguların Prosedürlere Benzerliği Örneğin Prolog daki bir kuralı diğer dillerdeki bir procedure olarak görmek mümkündür. sever(ahmet, Birsey):- sever(gul, Birsey). 54

65 Ģeklindeki bir kural Ahmet in bir Ģeyi sevdiğini ispatlamak için, Gül ün de aynı Ģeyi sevdiğini ispat et anlamına gelir. Aynı Ģekilde sever(orhan, Baklava). Ģeklindeki Prolog kuralı Orhan ın baklava sevdiğini ispat etmek için dur anlamındaki bir procedure olarak düģünmek mümkündür. Burada sever(kim, Ne) Ģeklinde bir sorgu gelirse, Kim ve Ne serbest değiģkenleri sırasıyla Orhan ve Baklava değerlerini alırlar. Case ifadesi, boolean testleri ve goto komutu diğer dillerde mevcut olan procedure örnekleridir. Benzer iģlemleri, kuralları kullanarak yapabiliriz Bir Kuralın Case ifadesi Gibi Kullanılması Prolog daki Kural ile diğer dillerdeki Procedure arasındaki büyük farklardan biri, Prolog un aynı procedure için birden fazla alternatif tanımlama imkanı vermesidir. Pascal daki CASE ifadesi kullanıyormuģ gibi, her argüman değeri için farklı bir tanım yazarak çoklu tanım kullanabilirsiniz. Prolog kuralları peģpeģe kullanarak eģleģenleri bulur ve kuralın tanımladığı iģlemi yapar. Örnek: PREDICATES nondeterm basilan_tus(integer) CLAUSES basilan_tus(1):- nl, write("1 TuĢuna Bastınız."), nl. basilan_tus(2):- nl, write("2 TuĢuna Bastınız."), nl. basilan_tus(3):- nl, write("3 TuĢuna Bastınız."), nl. basilan_tus(n):- nl, 55

66 N<>1, N<>2, N<>3, write("hangi TuĢa Bastığınızı Bilmiyorum"), nl. GOAL write("1-3 arasında bir sayı yazınız: "), readint(sayi), basilan_tus(sayi). Örnekte, 1, 2 veya 3 haricindeki rakamlar girildiğinde eģleģme olamaz ve çözüm bulunmaz Bir Kural İçinde Test Yapmak Yukarıdaki örnekte geçen basilan_tus(n) cümleciğinde; verilecek herhangi bir değere otomatik olarak N e atanacaktır. Burada verilen sayının sadece 1-3 aralığı dıģında olması durumunda Hangi TuĢa Bastığınızı Bilmiyorum mesajının görüntülenmesi gerekir. Bu N<>1, N<>2, N<>3 alt hedefleri ile gerçekleģtirilmektedir. Prolog ilk önce yazılan değerin 1-3 arasında olup olmadığını doğrulamaya çalıģır. Doğru olmadığını görünce geriye dönüģ iģlemi yapmaya çalıģır. Fakat baģka alternatif olmadığı için bu cümlenin geriye kalan kısmına geçiģ yapamaz. Basilan_tus iliģkisi atanacak olan seçeneklere dayanır. Eğer basilan_tus iliģkisi argümanı serbest olan bir değiģken ile çağılırsa, GOAL bu cümlelerin hepsiyle eģleģir ve ilk üç kural alternatif çözümler olarak sunulur. Son cümle ise hataya neden olur. Çünkü bağımsız bir değiģkeni bir sayı ile eģleģtirmek mümkün değildir Cut Komutunun Goto Gibi Kullanılması Yukarıdaki örnek vakit kaybına neden olur. Çünkü doğrulanan bir kural bulunsa bile, Prolog un son kuralı da test edip baģka alternatif araması gerekir. Prolog a alternatif aramaktan vazgeçmesini söylemek için Cut komutu kullanılabilir. Bunun sonucu, bize zaman ve bellek tasarrufu sağlanır. Yukarıdaki program, Ģimdi de Cut komutu ile yazılsın. PREDICATES nondeterm basilan_tus(integer) CLAUSES basilan_tus(1):-!, nl, write("1 TuĢuna Bastınız."), nl. basilan_tus(2):-!, 56

67 nl, write("2 TuĢuna Bastınız."), nl. basilan_tus(3):-!, nl, write("3 TuĢuna Bastınız."), nl. basilan_tus(_):-!, write("hangi TuĢa Bastığınızı Bilmiyorum"), nl. GOAL write("1-3 arasında bir sayı yazınız: "), readint(sayi), basilan_tus(sayi). Cut komutunun iģleme girebilmesi için Prolog un içinde Cut bulunan bir kurala gitmesi ve Cut komutunun bulunduğu noktaya kadar gelmiģ olması gerekir. Cut komutu basilan_tus(x):- X>3,!, write( Yazdığınız rakam çok yüksek ) gibi testlerden önce gelebilir. X>3 alt hedefi doğrulandığı anda Cut komutu önemli hale gelir. Burada kuralların sırası oldukça önemlidir. 13. örnekte kurallar; arzu edilen sıraya göre yazılabilir. Çünkü onlardan sadece biri girilen bir sayı ile eģleģir. Fakat Cut kullanılan yukarıdaki örnekte, bilgisayarın write("hangi TuĢa Bastığınızı Bilmiyorum") kuralına diğer üç kuralı denemeden önce kesinlikle geçmediğinden emin olmak gerekir. Çünkü buradaki Cut komutları red_cut, yani olumsuz cut, görevi görürler ve programın mantığını değiģtirirler. Eğer yukarıdaki programda X<>1, X<>2 ve X<>3 Ģeklindeki karģılaģtırma anahtarlarını tutup her cümleye sadece bir Cut komutu yerleģtirilirse, buradaki Cut komutları Green Cut olarak görev yaparlar. Cut, diğer programlama dillerinde tıpkı GOTO komutu gibi görev görür. Cut komutunun kullanımı faydalıdır, fakat içinde Cut kullanılan programları anlamak bazen zor olabilir Hesaplanmış Değerleri Görüntüleme Program akıģında, ilk baģta herhangi bir değeri olmayan argümanlar, daha sonra belirli değerle alırlar. Örneğin sever(orhan, gulsah). Ģeklindeki bir olgu sever(orhan, Kim) Ģeklindeki bir hedef cümlesindeki Kim argümanına Gulsah değerini atamıģ olur. Yani 57

68 GOAL sever(orhan, Kim) hedef cümlesindeki Kim argümanı ilk önce serbest olmasına rağmen, sever(orhan, gulsah) olgusunu çağırdığı anda olgudaki Gulsah değeri Kim argümanına atanır ve Kim argümanı sınırlı hale gelir. Örnek: PREDICATES nondeterm ekrana_yaz(integer, symbol) CLAUSES ekrana_yaz(0, sifir). ekrana_yaz(sayi, negatif):- Sayi<0. ekrana_yaz(sayi, pozitif):- Sayi>0. GOAL ekrana_yaz(14, Sayinin_isareti). ekrana_yaz iliģkisinin ilk argümanı daima sabit bir sayı ve bağlı bir değiģken olmak zorundadır. Ġkinci argüman ise sınırlı veya sınırsız bir değiģken olabilir. Ġlk değiģkene bağlı olarak sıfır, negatif veya pozitif bir sayı olabilir. Yukarıdaki GOAL cümleciğinin bulacağı cevap elbette yes olacaktır. Çünkü 14 sıfırdan büyük bir sayıdır ve pozitiftir. Burada sadece 3. cümlecik doğrudur. GOAL ekrana_yaz(14, negatif). Hedef cümlesiyle aynı prosedür takip edilir ve no cevabı alınır. Prolog un sonuç alması incelenirse, Ġlk önce ilk cümlecik incelenir. Belirle iliģkisindeki argümanlar, yani 14 ve negatif değerleri, 0 ve sifir değerleriyle eģleģmezler. Ġkinci cümleciğe sıra geldiğinde, Sayi 14 e eģitlenir fakat sayi<0 testi doğrulanamaz. Üçüncü argümana gelindiğinde bu kez ikinci argümanlar eģleģmez, yani pozitif kelimesi negatif ile eģleģemez. Anlamlı bir cevap almak için örneğin GOAL belirle(14, Sayinin_Isareti) kullanılırsa, Sayinin_Isareti=pozitif 1 Solution cevabı alınır. Yukarıdaki örneğin çalıģması esnasında, iģlemler aģağıdaki sıra ile yapılacaktır. 58

69 ekrana_yaz(14, Sayinin_Isareti) hedef cümlesi, ilk cümleciğin ekrana_yaz(0, sifir) kısmıyla eģleģmez. Bu yüzden ilk cümlecik kullanılamaz. 1. ekrana_yaz(14, Sayinin_Isareti) hedef cümlesi ikinci cümleciğin baģ kısmıyla eģleģir ve Sayi=14, Sayinin_Isareti=negatif olur. Fakat hemen sonraki Sayi<0 yanlıģ olduğundan Prolog bu cümlecikten geriye döner ve Sayi=14 değeri iptal edilir. 2. ekrana_yaz(14, Sayinin_Isareti) hedef cümlesi üçüncü cümleciğin baģ kısmıyla eģleģir ve Sayi=14, Sayinin_Isareti=pozitif olur. Sayi>0 eģitliği de sağlandığı için Prolog artık geriye iz sürme iģlemini yapmaz ve sonucu görüntüler. 59

70 5. BASİT VE BİLEŞİK NESNELER ġimdiye kadar Prolog da kullanılan veri nesnelerinden number, symbol, string gibi birkaç tip incelenmiģtir. Bu bölümde basit ve bileģik veri türlerinin tamamı incelenecektir. Standart tip olarak tanımlanabilen veriler, bazı bileģik veri yapılarını içermezler. Bu yüzden farklı veri yapılarına göz atarak, bunların domains ve predicates bölümlerinde nasıl tanımlanabileceği göreceğiz Basit veri nesneleri Basit bir veri nesnesi, bir değiģken veya bir sabitten oluģabilir. Sabit, constants bölümünde tanımlanan veri tipi değil; char, integer, symbol, string gibi değiģmeyen bir nesnedir Veri Nesneleri Olan Değişkenler VIP değiģkenleri A-Z arasındaki büyük bir harf veya (_) ile baģlamalıdır. (DeğiĢken isimlerinde ç, Ġ, ö, ğ, Ģ vs. gibi Türkçe karakterler kesinlikle kullanılamaz) Yalnız baģına kullanılan (_) değiģkeninin anonim değiģken olduğunu ve herhangi bir değerle eģleģebileceği bilinmektedir. Prolog daki değiģkenler global değil, lokaldir. Yani iki ayrı cümlecikte aynı isimle -örneğin X- gösterilen bir değiģken farklıdır. EĢleĢme sırasında birbiriyle eģleģebilir, fakat temelde birbiri üzerinde hiçbir etkisi yoktur Veri Nesneleri Olan Sabitler Sabitler karakter, sayı veya atom biçiminde olabilirler Karakterler Karakterler char kelimesi ile gösterilir ve 0-9, A-Z ve a-z, ASCII 127 karakter tablosundaki değerleri alabilirler. Fakat ASCII 32 (boģluk) ve daha küçük karakterler kontrol amacıyla kullanılırlar. Tek karakterlik bir sabit Ģöyle yazılır: a 3 * W A \\ =\ \ = \225 = (ASCII 225) 60

71 Bunların dıģında baģka fonksiyonları olan karakterler de vardır. \n Yeni satıra geçiģ komutu \r Satır sonu \t Yatay sekme (tab) Sayılar Sayılar tamsayı ve reel olabilirler. Reel sayılar arasında değiģirler. Örnek: Tamsayılar Reel Sayılar * Atomlar Bir atom symbol veya string olabilir. Ġkisi arasındaki fark genelde Prolog un çalıģtırıldığı sisteme bağlıdır. Prolog string ve symbol tipleri arasında otomatik dönüģtürme yapabilir. Dolayısıyla symbol ve string tipindeki değiģkenler birbirinin yerine kullanılabilirler. Fakat programcılıkta yaygın olan adet, çitf tırnak ( ) içine alınması gereken sabitleri string, çitf tırnak gerektirmeyen sabitleri de symbol olarak kabul etmektir. Symbol: küçük harfle baģlayan ve sadece harf, rakam ve _ karakterlerini içerir. String: Çift tırnak içine alınabilen ve string sonunu belirleyen 0 (Sıfır) hariç, herhangi bir karakteri içerebilir. Symbol String Yemek Yavuz AYDIN Ahmetin_babasi 12. Cadde A a PdcProlog Visual Prolog Development Center 61

72 5.2. Bileşik Veri Nesneleri ve Fonksiyon Operatörleri BileĢik veri nesneleri, birden fazla parçadan oluģan verileri tek bir parçaymıģ gibi kullanma imkanı tanır. Mesela 16 Mayıs 1998 tarihi gün, ay ve yıl olarak 3 parçadan oluģan bir bilgiyi temsil eder. Bu tür bir bilgiyi tek bir parçaymıģ gibi kullanmaya imkan tanıyan sabitler vardır. Örnek: Domains Islem_tarihi= date(string, unsigned, unsigned) Ģeklindeki bir tanımdan sonra D=date( Mayıs, 16, 1998) Ģeklinde yazılabilir. Burada D bir olgu değil, symbol veya sayı gibi kullanılabilecek bir veridir. Bu tür ifadeler genelde bir fonksiyon operatörü ve takip eden 3 argüman ile baģlar. Operatörler herhangi bir hesaplama yapamazlar. Sadece bir tür bileģik veri nesnelerini tanımlar ve argümanların tek veriymiģ gibi tutulmasına imkan tanır. BileĢik veri nesnelerinin argümanları da bileģik olabilir. Örneğin Dogum_Gunu Kisi date Ahmet SAGMEN Mart Ģeklinde gösterilen bir tarihi Prolog da dogum_tarihi(kisi( Ahmet, SAGMEN ),date( Mart,15,1976)) Ģeklinde yazılabilir. Bu örnekte dogum_tarihi bileģik nesnesinin iki bölümü vardır: kisi( Ahmet, SAGMEN ) ve date( Mart, 15, 1976). Buradaki operatörler kisi ve date dir Bileşik Nesnelerin Eşleştirilmesi BileĢik bir nesne basit bir değiģken veya kendisine uyan diğer bir bileģik nesne ile eģleģebilir. Örneğin date( Nisan, 18, 1983) Ģeklindeki bir clause tarih clause una tam olarak eģleģir. Aynı Ģekilde date( Nisan, 18, 1983) date(ay, Gun, Yil) cümleciğinde Ay=Nisan, Gun=18, Yil=1983 değerlerine atanır. 62

73 5.4. Bileşik Nesneleri Eşleştirmek İçin = Sembolünün Kullanılması VIP iki durumda eģleģtirme iģlemi yapar. Ġlki bir Goal veya çağrı fonksiyonunun bir cümleciğin baģ kısmıyla eģleģmesi durumunda meydana gelir. Ġkincisi ise = iģaretinin argümanlar arasında kullanılması durumunda meydana gelir. Prolog, eģitliğin her iki tarafındaki aynı iģaretli nesneleri eģleģtirmek için gerekli bağlantıları yapar. AĢağıdaki örnekte, soy isimleri aynı olan iki kiģiyi bulup her ikisinin adreslerini eģitleyelim. DOMAINS sahis=sahis(isim, adres) isim=isim(adi, soyadi) adres=adres(cadde, sehir, ulke) cadde=cadde(cadde_no, cadde_ismi) sehir, ulke, cadde_ismi=string adi, soyadi= string cadde_no= integer GOAL P1 = sahis(isim(orhan, aydin), adres(cadde(5, "1. Cadde"), "Elazig", "Turkiye")), P1= sahis(isim(_, aydin), Adres), P2= sahis(isim(oktay, aydin), Adres), write("birinci Sahis =", P1), nl, write("ġkinci Sahis =", P2), nl Birden Fazla Nesneyi Tek Nesne Olarak Kullanmak Prolog da yazılmıģ programlarda bileģik nesneleri tek bir nesne gibi kullanmak kolaydır. Bu da programcılığı oldukça kolaylaģtırır. Örneğin sahiptir(fatih, kitap( Visual Prolog Ġle Programlama, Prof.Dr. Asaf VAROL )). cümlesi Fatihin Prof.Dr. Asaf Varol tarafından yazılan Visual Prolog ile Programlama adlı bir kitabı var anlamındadır. Benzer Ģekilde; sahip(fatma, sevgili(can)). 63

74 cümlesi Fatma nın, ismi Can olan bir sevgilisi var anlamına gelir. kitap( Visual Prolog Ġle Programlama, Prof.Dr. Asaf VAROL ) ve sevgili(can) cümlelerdeki bileģik nesnelerdir. BileĢik nesne kullanmanın önemli bir avantajı, birden fazla argümandan oluģan cümleleri sadece bir argüman olarak kullanabilmektir. Örnek: Basit bir telefon rehberi veritabanı programı PREDICATES Adres_listesi(symbol, symbol, symbol, symbol, integer, integer) /*(adi, soyadi, telefonu, ay, gun, yil)*/ clauses adres_listesi(davut, yildirim, , ocak,6, 1978). adres_listesi(maksut, hazneci, , nisan,14, 1969). adres_listesi ndeki 5 argümanı sahis(adi, Soyadi), dogum_tarihi(ay,gun,yil). Ģeklinde yazmak mümkündür. Yeni Ģekliyle program Ģöyle yazılabilir: Domains Adi= sahis(symbol, symbol) /* (Adi, Soyadı)*/ Dogum_tarihi= d_tarihi(symbol, integer, integer) /*(Ay, Gün, Yıl)*/ Telefon_no= symbol /* Telefon no*/ Predicates adres_listesi(adi, telefon_no, d_tarihi) clauses adres_listesi(sahis(davut, yildirim), , d_tarihi(ocak,6, 1978)). adres_listesi(sahis(maksut, hazneci), , d_tarihi(nisan,14, 1969)). ġimdi yukarıdaki küçük programa birkaç kural daha ilave edip, doğum tarihleri bugünün tarihi ile uyuģanları bulmaya çalıģalım. Programda standart yüklem olan date kullanılarak bugünün tarihi bilgisayardan alınacaktır. DOMAINS adi = sahis(symbol,symbol) /* (Adı, Soyadı) */ dogum_gunu = d_gunu(symbol,integer,integer) /* (Ay, Gun, Yıl) */ 64

75 tel_no = symbol /* Telefon Numarası */ PREDICATES nondeterm tel_listesi(adi,symbol,dogum_gunu) d_gunu_ayini_bul ay_donustur(symbol,integer) d_gunu_ayini_kontrol_et(integer,dogum_gunu) sahsi_yaz(adi) CLAUSES d_gunu_ayini_bul:- write("====bu ay doğanların listesi ======="),nl, write(" Adı\t\t Soyadı\n"), write("=============================="),nl, date(_, Bu_ay, _), /* Tarihi bilgisayardan oku */ tel_listesi(sahis, _, Date), d_gunu_ayini_kontrol_et(bu_ay, Date), sahsi_yaz(sahis), fail. d_gunu_ayini_bul:- write("\n\n Devam etmek için herhangi bir tuģa basın "),nl, readchar(_). sahsi_yaz(sahis(adi,soyadi)):- write(" ",Adi,"\t\t ",Soyadi),nl. d_gunu_ayini_kontrol_et(yeni_ay,d_gunu(ay,_,_)):- ay_donustur(ay,ay1), Yeni_ay = Ay1. tel_listesi(sahis(paki, turgut), " ", d_gunu(ocak, 3, 1965)). tel_listesi(sahis(arif, gurel), " ", d_gunu(subat, 5, 1972)). tel_listesi(sahis(mehmet_can, hallac), " ", d_gunu(mart, 3, 1965)). tel_listesi(sahis(cuma, cetiner), " ", d_gunu(nisan, 29, 1963)). tel_listesi(sahis(omer, akgobek), " ", d_gunu(mayis, 12, 1971)). tel_listesi(sahis(fatih, dilekoglu), " ", d_gunu(haziran, 17, 1970)). 65

76 tel_listesi(sahis(levent, aksun), " ", d_gunu(haziran, 20, 1972)). tel_listesi(sahis(cengiz, gok), " ", d_gunu(temmuz, 16, 1973)). tel_listesi(sahis(kasim, yenigun), " ", d_gunu(agustos, 10, 1968)). tel_listesi(sahis(husamettin, bulut), " ", d_gunu(eylul, 25, 1967)). tel_listesi(sahis(arif, demir), " ", d_gunu(ekim, 20, 1992)). tel_listesi(sahis(sezen, demir), " ", d_gunu(kasim, 9, 1980)). tel_listesi(sahis(nebahat, arslan), " ", d_gunu(kasim, 15, 1987)). tel_listesi(sahis(leyla, aydin), " ", d_gunu(aralik, 24, 1940)). ay_donustur(ocak, 1). ay_donustur(subat, 2). ay_donustur(mart, 3). ay_donustur(nisan, 4). ay_donustur(mayis, 5). ay_donustur(haziran, 6). ay_donustur(temmuz, 7). ay_donustur(agustos, 8). ay_donustur(eylul, 9). ay_donustur(ekim, 10). ay_donustur(kasim, 11). ay_donustur(aralik, 12). GOAL d_gunu_ayini_bul. Yukarıdaki program kodu incelendiğinde, bileģik nesnelerin neden faydalı olduğu açıkça görülür. Dogum_tarihi_ayi yüklemi, en yoğun kullanılan cümle durumdadır. 1. Program ilk önce sonuçları bir pencerede görüntüler. 2. Sonra sonuçların yorumlanacağı bir baģlık kısmı görüntülenir. 3. Daha sonra hazır fonksiyonlardan biri olan date kullanılarak bilgisayarın saatinden bugünkü tarih okunur ve ay belirlenir. 4. Bundan sonra yapılması gereken tek Ģey, satırlar halinde sıralanan veritabanından isim, telefon no, doğum tarihi okutmaktır. Burada doğum tarihi sistemden okunan ay ile karģılaģtırılıp aynı olanlar bulunur. adres_listesi(sahis,_, Date) çağrısı adı ve soyadını Sahis değiģkenine atar ve sahis operatörü Sahis a atanmıģ olur. 66

77 Date değiģkeni de ilgili Ģahsın doğum tarihini alır. Buradaki adres_listesi bileģik bir değiģken olup, bir kiģi hakkındaki bütün bilgileri saklar. 5. Daha sonra aranan kiģinin doğum tarihini Date değiģkenine atar. Bir sonraki alt hedefte tamsayıyla gösterilen bugünkü ay ve kiģinin doğum tarihi dogum_gununu_kontrol_et yüklemine iletilir. 6. dogum_gununu_kontrol_et yüklemi iki değiģkenle birlikte çağrılır. Ġlk değiģken bir tamsayıya, ikincisi ise dogum_tarihi ne bağlanır. dogum_gununu_kontrol_et kuralını tanımlayan kuralın baģ kısmındaki Bu_ay Mon değiģkenine atanır. Ġkinci argüman olan Date ise dogum_tarihi(ay, _,_) cümleciğine atanır. Sadece bugünkü tarihten ay ile ilgilendiğimiz için, gün ve yıl için anonim değiģkenler kullanılmıģtır. 7. dogum_gununu_kontrol_et yüklemi ayın sembolik değerini tam sayıya dönüģtürür ve bu değeri sistemden okunan ay değeri ile karģılaģtırır. KarĢılaĢtırmanın baģarılı olması durumunda bir sonraki alt hedefe geçer. KarĢılaĢtırma baģarısız olursa geriye iz sürme iģlemi baģlar. 8. ĠĢlenmesi gereken bir sonraki alt hedef adini_yaz dır. Ġstenilen bilgi, doğum tarihi bu ay olan kiģinin ismi olduğu için, ekrana bu kiģinin adı ve soyadı yazılır. Bir sonraki cümle fail olduğu için otomatik olarak geriye iz sürme iģlemi baģlar. 9. Geriye iz sürme daima en son kullanılan non-deterministic yükleme geri gider. Bizim programımızda zaten non-deterministic bir yüklem bulunduğu için iģlem hemen adres_listesi ne gider. Program burada iģleme konmak üzere baģka bir isim aramak için veritabanına gider. Eğer veritabanında iģleme konacak baģka biri kiģi yoksa iģlemdeki cümle baģarısız olur. Prolog, veritabanındaki diğer satırları inceler ve dogum_gununu_kontrol_et kuralını tanımlayan baģka bir cümle bulur Bileşik Nesnelerin Tiplerini Tanımlamak Bu bölümde bileģik nesne tiplerinin nasıl tanımlanacağı üzerinde duralım. sahiptir(ahmet, kitap( Pascal 7, Ömer AKGÖBEK )) sahiptir(ahmet, at(firtina)). Ģeklinde tanımlanan iliģkiler GOAL sahiptir(ahmet, Ne) 67

78 sorgusuyla irdelenirse Ne değiģkeni iki ayrı argüman ile eģleģebilir. Bunlardani biri kitap, diğeri ise at tır. Sahiptir yüklemi artık sahiptir(symbol, symbol) Ģeklinde tanımlanamaz. Ġkinci argüman symbol tipindeki nesnelere iģaret etmez. Bunun yerine sahiptir(isim, esyalar) Ģeklinde bir yüklem tanımlamak mümkündür. Tipleri tanımlarken Domains esyalar= kitap(kitap_adi, yazar); at(atin_adi) kitap_adi, yazar, atin_adi = symbol yazılabilir. Yukarıdaki ; iģareti veya anlamına gelir. Bu durumda iki alternatiften bahsetmek mümkündür. Bir kitap, kitabın adı ve yazarının adıyla, bir at ise sadece ismiyle tanımlanabilir. Kitap_adi, yazar, atin_adi değiģkenlerinin tamamı symbol tipindedir. Tip tanımlanmasına daha fazla alternatif rahatlıkla ilave edilebilir. Örnek DOMAINS esyalar= kitap(kitap_ismi, yazar); at(atin_adi); araba; banka_hesabi(nakit) kitap_ismi, yazar, atin_adi=symbol nakit = real isim=symbol PREDICATES nondeterm sahiptir(isim, esyalar) CLAUSES sahiptir(ahmet, kitap("pascal 7.0", "Ömer AKGÖBEK")). sahiptir(ahmet, at(firtina)). sahiptir(ahmet, araba). sahiptir(ahmet, banka_hesabi(1000)). GOAL sahiptir(kim, Sahip_oldugu_esyalar). Programı derlenip çalıģtırıldığında Sahip_oldugu_esyalar=kitap( Pascal 7.0, Ömer AKGÖBEK )). Sahip_oldugu_esyalar=at(firtina)). 68

79 Sahip_oldugu_esyalar=araba Sahip_oldugu_esyalar= banka_hesabi(1000)). 4 Solutions cevabı görüntülenir Tip Tanımlamaları Üzerine Kısa Bir Özet BileĢik nesnelerin tip tanımları genel bir Ģekilde gösterilecek olursa: Domain= alternatif1(tip, Tip,...); alternatif2(tip, Tip,...) Burada alternatif1 ve alternatif2 farklı operatörlerdir. (Tip, Tip,...) gösterimi standart veya baģka yerde ayrıca tanımlanan symbol, integer, real vs. gibi tip isimlerdir. Not: 1. Alternatifler birbirinden daima ; ile ayrılırlar. 2. Her alternatif bir operatör ve bu argümana ait tip tanımlarını içerir. 3. Eğer operatörde herhangi bir argüman kullanılmazsa, bunu alternatifn veya alternatifn( ) biçiminde yazılabilir Çoklu-Düzey Bileşik Nesneler Prolog da, birden fazla dereceden oluģan bileģik nesne kullanmak mümkündür. Örneğin kitap( Atatürk: Bir Milletin Yeniden DoğuĢu, Kinross ) olgusundaki Kinross soyismi yerine, yazarın adını ve soyadını ayrıntılı olarak gösteren bir yapı kullanmak mümkündür. kitap( Atatürk: Bir Milletin Yeniden DoğuĢu, yazar( Lord, Kinross )) Daha önceden yapılan tip tanımında kitap(kitap_adi, yazar) yazılıyordu. Ġkinci argüman olan yazar, operatör durumundadır. Fakat yazar=symbol sadece bir isimi kapsadığından, yetersiz kalır. Bu durumda yazar değiģkeninin de bileģik nesne olarak tanımlanması gerekir. Bunu da: yazar=yazar(isim, soyisim) Ģeklinde tanımlamak mümkündür. ġimdi tip tanımlarına geçelim. 69

80 Domains esyalar=kitap(kitap_adi, yazar); /*Ġlk derece*/ yazar=yazar(adi, soyadi) /*ikinci derece*/ kitap_adi, isim, soyisim=symbol /*Üçüncü derece*/ Birden fazla dereceden oluģan bileģik nesneler kullanırken, ağaç biçiminde bir yapı kullanmak büyük kolaylık sağlar. Kitap Kitap_adi yazar Ġsim, soyisim Tip tanımı yapılırken bir anda ağaç yapısının sadece bir derecesi kullanılabilir. Örneğin kitap=kitap(kitap_adi, yazar(adi, soyadi)) ġeklindeki tip tanımı yanlıģtır Çoklu-Tipli Argümanlar Bir yüklemin farklı tiplerde bilgi verebilmesi için bir operatör tanımının yapılması yapmamız gerekir. AĢağıdaki örnekte sizin_yasiniz cümleciği yas argümanını kabul edilmektedir. Yas argümanı ise string, real veya integer olabilir. DomaIns yas=i(integer); r(real); s(string) Predicates siniz_yasiniz(yas) CLAUSES sizin_yasiniz(i(yas)):-write(yas). sizin_yasiniz(r(yas)):-write(yas). sizin_yasiniz(s(yas)):-write(yas) Listeler Öğretim üyelerinin verdikleri dersleri liste halinde saklamak istediğimizi kabul edelim. Bunun için aģağıdaki kodun yazılması yeterlidir. PREDICATES 70

81 profesor(symbol, symbol,symbol) /*Adı, soyadı ve verdiği ders*/ CLAUSES profesor(asaf, varol, bilgisayar). profesor(ali, erdogan, betonarme). profesor(ahmet, aydogan, fizik). Bu tür bir programda, bütün hocaların isimlerini ve verdikleri dersleri tek tek sıralamak mümkündür. Her hoca için ayrı bir olguyu veritabanına ilave etmek gerekir. Kolay görünen bu iģin yüzlerce öğretim üyesi olan bir üniversite için yapıldığında ne kadar zor olduğunu açıktır. Prolog daki liste bir veya daha fazla değer alabilir ve benzer iģlerde büyük kolaylıklar sağlar. Bir listedeki değiģkenlerin aldıkları değerleri [] arasında yazmak gerekir. DOMAINS dersler=symbol* PREDICATES profesor(symbol, symbol, dersler) CLAUSES profesor(asaf, varol, [bilgisayar, termodinamik, iklimlendirme]). profesor(ali, erdogan, [betonarme, statik, malzeme]). profesor(ahmet, aydogan, (fizik, matematik, kimya]). ġeklindeki satırlarda dersler liste tipinde bir değiģken olarak tanımlanmıģtır. Buradaki * sembolü dersler değiģkeninin liste tipinde olacağını gösterir. Aynı biçimde, listenin tamsayılardan oluģtuğu bir değiģken tipi Domains tamsayilar_listesi=integer* Ģeklinde tanımlanabilir. Örnek: DOMAINS notlar=integer* PREDICATES nondeterm sinav_sonuclari(symbol, symbol, notlar) CLAUSES 71

82 sinav_sonuclari(orhan, aydin, [78, 98, 100]). sinav_sonuclari(kasim, yenigun, [45, 54, 60]). sinav_sonuclari(husamettin, bulut, [80, 90, 95]). sinav_sonuclari(huseyin, karasu, []). GOAL sinav_sonuclari(orhan,_,aldigi_notlar). Programı çalıģtırıldığında Orhan ın aldığı notlar görüntülenir. 72

83 6. TEKRARLAMA VE REKÜRSİYON Prosedür ve veri yapılarında tekrarlama iģlemleri Visual Prolog da kolay bir Ģekilde yapılır. Bu bölümde önce tekrarlı iģlemler (döngüler ve rekursif prosedürler), daha sonra ise rekursiv veri yapıları incelenecektir Tekrarlı İşlemler Pascal, BASIC veya C gibi konvansiyonel programlama dilleriyle çalıģanlar, Prologla çalıģmaya baģladıklarında FOR, WHILE, REPEAT gibi ifadeleri göremeyince ĢaĢırabilirler. Çünkü Prologda iterasyonu anlatan direkt bir yol yoktur. Prolog sadece iki türlü tekrarlama-geriye dönüģ imkanı tanır. Bu iģlemlerde bir sorguya birden fazla çözüm bulmak ve bir prosedürün kendisini çağırdığı rekürsiyon iģlemine imkan tanır Geriye İz Sürme Bir prosedür, istenilen bir hedef için uygun bir çözüm yerine alternatif baģka çözümler aramak için geriye döner. Bunun için geriye henüz denenmemiģ bir alternatifi kalan en son alt hedefe gidileceğini, bu noktadan tekrar aģağıya doğru inileceği bilinmektedir. Geriye dönüģü iptal edip tekrarlı iģlemler yaptırmak mümkündür. Örnek: PREDICATES nondeterm ulke_adi(symbol) ulke_adlarini_yaz CLAUSES ulke_adi("türkiye"). ulke_adi("kazakistan"). ulke_adi("azerbaycan"). ulke_adi("amerika"). ulke_adlarini_yaz:- ulke_adi(ulke), write(ulke), nl, fail. ulke_adlarini_yaz. GOAL ulke_adi(ulke). 73

84 Yukarıdaki ulke_adi yüklemi sadece ülke isimlerini sıralar. Dolayısıyla GOAL ulke_adi(ulke) Ģeklindeki bir hedefin birden fazla sonucu vardır ve ulke_adlarini_yaz yuklemi bunların hepsini görüntüler. ulke_adlarini_yaz :- ulke_adi(ulke), write(ulke), nl, fail. satırıyla söylenmek istenen Ģey Ģudur: Bütün ülke isimlerini yazmak için, önce ulke-adi(ulke) cümlesine cevap bul, bunu yaz, yeni bir satıra geç ve iģlemi yeniden baģlat. fail komutunun programa yüklediği görev Ģöyle özetlenebilir: GOAL cümlesine uygun bir çözüm bulunduğunda, geriye dönüģ yap ve baģka alternatiflere bak. fail yerine, sonucu daima yanlıģ olan ve bu yüzden geriye dönüģü zorlayan baģka bir alt hedef kullanmak mümkündür. Örneğin, 10=5+6 satırı her zaman yanlıģ olacağı için, Prolog baģka alternatifler bulmak için daima geriye dönüģ yapar. Örneğimizde ilk önce Ulke=Türkiye olur ve sonuç ekrana yazılır. fail komutuna sıra geldiğinde program, bir alt hedefe geri döner. Fakat nl veya write(ulke) satırları için kullanılabilecek herhangi bir veri olmadığı için, bilgisayar ulke_adi(ulke) iliģkisi için baģka çözümler arar. Ulke_adi(Ulke) iliģkisi çalıģtırıldığında, önceden boģ değiģken olan Ulke değiģkeni Türkiye değerini almıģtı. Bu yüzden bu iliģkiyi yeniden kullanmadan önce Ulke değiģkeni yeniden serbest hale getirilir. Daha sonra Ulke değiģkeninin alabileceği baģka bir olgu aranır. Ġkinci oluguda bu sağlanır ve ulke_adi yüklemindeki Ulke değiģkeni Kazakistan değerini alır. Bu iģlem böylece devam eder ve sonuçta Ģu satırlar görüntülenir. Türkiye Kazakistan Azerbaycan Amerika 4 Solutions Eğer ulke_adlarini_yaz yüklemi fail komutundan sonra yazılmamıģ olsaydı, cevap yine aynı olurdu fakat yes yerine no satırı görüntülenirdi. 74

85 6.3. Önceki ve Sonraki Eylemler Bir hedef için gerekli olan bütün çözümleri sağlayan bir program, çözüm yapmadan ve yaptıktan sonra baģka Ģeyler de yapabilir. Örneğin 1. YaĢanacak güzel yerler 2. Ulke_adi(Ulke) yükleminin bütün sonuçlarını yaz. 3. BaĢka yerler de olabilir... ġeklinde bir mesaj yazarak bitirebilir. Ulke_adlarini_yaz cümlesin ulke_adi(ulke) yükleminin bütün sonuçlarını içerir ve sonunda bir bitiģ mesajı yazar. Örnekte geçen ilk ulke_adlarini_yaz cümlesi yukarıdaki adımlardan ikincisi içindir ve bütün çözümleri yazar. Ġkinci cümlesi ise üçüncü adıma tekabül eder ve sadece hedef cümlesini baģarılı bir Ģekilde bitirmek içindir. Çünkü ilk cümle daima yanlıģtır. Programı baģka Ģekilde yazmak gerekirse: PREDICATES nondeterm ulke_adi(symbol) ulke_adlarini_yaz CLAUSES ulke_adi("türkiye"). ulke_adi("kazakistan"). ulke_adi("azerbaycan"). ulke_adi("amerika"). ulke_adlarini_yaz:- write("yaģanacak bazı yerlerin listesi.."), nl, fail. ulke_adlarini_yaz :- ulke_adi(ulke), write(ulke), nl, fail. ulke_adlarini_yaz:- write("baģka güzel yerler de vardır..."), nl. GOAL ulke_adlarini_yaz. Ġlk cümledeki fail komutu çok önemlidir. Çünkü bu komut ilk cümle çalıģtırıldıktan sonra programın ikinci cümleye geçiģini sağlar. Buradaki write ve nl 75

86 komutlarının baģka bir iģ yapmaması çok önemlidir. Son fail komutundan sonra programın ikinci cümleciğe geçiģi sağlanmalıdır Döngülü Geriye Dönüşün Uygulanması Geriye dönüģ iģlemi bir hedefin bütün çözümlerinin bulunması açısından son derece önemlidir. Birden fazla çözüm sunamayan hedefler için yine de geriye dönüģ iģlemi yapılabilir. Bu da tekrarlama iģlemini yapar. Örneğin: tekrar. tekrar:-tekrar. gibi iki cümlecik sonsuz sayıda çözüm olduğunu göstermektedir. Örnek: PREDICATES nondeterm tekrar nondeterm karakteri_ekrana_yaz CLAUSES tekrar. tekrar:-tekrar. karakteri_ekrana_yaz:- tekrar, readchar(harf), /*Klavyeden girilen harfi oku ve C'ye ata*/ write(harf), Harf='\r',!. /* Satır sonu tuģuna (Enter/Return) basılmadıysa devam et*/ GOAL karakteri_ekrana_yaz, nl.yukarıdaki örnekte tekrar iģleminin nasıl yapılacağını görülebilir. Karakteri_ekrana_yaz:-... kuralı, Enter/Return basılmadığı müddetçe, klavyeden girilen kararterleri kabul edip ekranda gösteren bir prosedür tanımlamaktadır. Karakteri_ekrana_yaz kuralının çalıģma mekanizması Ģöyle sıralanabilir: 1. tekrar ı çalıģtır. (Hiçbir Ģey yapmaz) 2. bir karakter oku (Harf) 3. Harf karakterini yaz 4. Harf in satır sonu karakteri olup olmadığını kontrol et. 76

87 5. Eğer satır sonu elemanı ise, iģlemi bitir, değilse, geriye iz sürme iģlemini yap ve alternatif ara. Buradaki write ve readchar kurallarının hiçbiri alternatif sağlayamaz. Dolayısıyla geriye dönüģ hemen tekrar kuralına gider, bunun ise alternatif sunması tabiidir. 6. ĠĢlem devam eder. Bir karakter oku, onu ekrana yaz, satır sonu elemanı olup olmadığını kontrol et. Harf e değer atayan readchar(harf) yükleminin öncesine geriye dönüģ yapıldığı anda, Harf değiģkeni serbest hale gelir. DeğiĢken değerinin kaybolması geriye dönüģ iģlemi sayesinde alternatif çözümler elde etmek için çok önemlidir. Fakat geriye dönüģ iģlemi baģka bir iģ için kullanılamaz. Çünkü geriye dönüģ iģlemi alternatif ararken, iģlemleri birçok kez tekrar edebilir. Fakat bu tekrarlar sırasında bir tekrardan diğerine geçiģte hiçbir Ģey hatırlayamaz. Daha önce de söylediğimiz gibi, iģlemlerden sonra değer ataması yapılan değiģkenlerin tamamı, geriye dönüģ iģlemi sırasında bütün bu değerleri kaybederler. Böyle bir döngüde sayaç gibi bir Ģey kullanıp toplam, kayıt sayısı vs. gibi bir değeri tutmanın kolay bir yolu yoktur Rekursif Prosedürler Tekrarlama iģlemin yapmanın diğer bir yolu da rekursiyondur. Kendisini çağırabilen prosedüre rekursiv prosedür diyoruz. Rekursiv prosedürler çalıģırken yaptıkları iģlerin sayısını, toplamını veya iģlemlerin ara sonuçlarını saklayabilir ve bunları bir döngüden diğerine rahatlıkla aktarabilirler. Örnek: N sayısının faktoriyelini hesaplamak için 1. Eğer N=1 ise, faktoriyel=1 2. Diğer durumlarda N-1 in faktoriyelini bul ve bunu N ile çarp Ģeklindeki emirleri anlayıp uygulayan bir program yazalım. Örneğin 3 sayısının faktöriyelini bulmak için 2 nin faktöriyelini, 2 nin faktöriyelini bulmak için de 1 in faktöriyelini bulmamız gerekir. 1 in faktöryeli zaten bilindiğinden yapılması gereken tek Ģey 2 ve 1 in faktöriyellerini N sayısı olan 3 ile çarpmaktır. Görüldüğü gibi iģlemler burada sonsuza kadar gitmemektedir. ġimdi bunları Prolog ile ifade etmeye çalıģalım: PREDICATES 77

88 faktoriyel(unsigned, real) CLAUSES faktoriyel (1, 1):-!. faktoriyel (X, Faktoriyel_X):- Y=X-1, faktoriyel(y, Faktoriyal_Y), Faktoriyel_X=X*Faktoriyal_Y. GOAL X=6, faktoriyel(x, Faktoriyel). Programı 6 sayısının faktöriyelini bulur. Burada ilginç bir durum vardır. Bilgisayar faktöriyel iģleminin yarısında iken nasıl olur da faktöriyeli hesaplar? Faktöriyel kuralını X=6 olacak Ģekilde çağırılırsa, faktöriyel kendini X=5 için çağırılacaktır. Bu durumda X değeri 6 mı olacak 5 mi? Cevap şudur: Bilgisayar faktöriyel prosedürünün bir kopyasını oluģturur ve bu kopyayı çağır. Kopyanın kendini faktoriyel prosedürünün aynısıymıģ gibi çalıģır. Sadece argümanların ve değiģkenlerin kopyalarına ihtiyaç duyulur. Bu bilgi yığın olarak hafızada saklanır ve bir kural çağrıldığında her seferinde yeniden oluģturulur. Kural non-deterministic değil ise sona erdiği zaman bellek yığını sıfırlanır Rekursiyonun Avantajları BaĢka türlü güvenli bir Ģekilde ifade edilemeyen algoritmaları daha açık bir Ģekilde ifade edebilir. Mantıksal olarak iterasyondan çok daha basittir. Listeleri iģlemede çok yaygın olarak kullanılır. Rekursiyon iģlemi özellikle problem içerisinde dallanmaların mevcut olduğu, yani bir problemin çözümünün bir alt probleme bağlı olduğu durumlarda çok faydalıdır Sondan Rekursiyon Optimizasyonu Rekursiyon iģleminin en önemli dezavantajı, belleği fazlaca kullanmasıdır. Bir prosedür baģka bir alt prosedürü çağırdığında, çağrıyı yapan prosedürün çağrıyı yaptığı anki çalıģma durumu mutlaka kaydedilmelidir. Böylece çağrılan prosedürün 78

89 yapması gereken iģlem bittiği zaman, çağrıyı yapan prosedür kaldığı yerden iģleme devam edebilir. Bunun dezavantajı Ģudur: Örneğin bir prosedür kendisini 100 defa çağırırsa, her seferki durum kaydedileceği için tam olarak 100 değiģik durum hafızaya alınmıģ olur. Hafızaya alınan her duruma stack frame (yığın alanı) denir. 16 bitlik PC DOS sisteminde bu alan 64K ile sınırlı olup, ancak yığın alacak kapasitedir. 32 Bit lik sistemlerde teorik olarak bu alan GB düzeyine kadar çıkabilir, fakat bu kez de baģka engeller ortaya çıkar. Yığın alanın azaltmak için ne yapılabilir? Bir prosedürün, baģka bir prosedürü kendisinin en son adımı olarak çağırdığını düģünelim. Çağrılan prosedür görevini yaptıktan sonra, çağrıyı yapan prosedürün yapması gereken baģka Ģey kalmaz. Çağrıyı yapan prosedürün kendisin çalıģma anını kaydetmesi gerekmez, çünkü o andaki bilgi artık gereksizdir. Çağrılan prosedür biter bitmez, program akıģı normal biçimde devam eder. Bu durum daha açık olarak aģağıdaki Ģekilde ifade edilebilir. A prosedürünün B prosedürünü, B prosedürünün ise C prosedürünü son adım olarak çağırdığını düģünelim. B prosedürü C yi çağırdığında, B nin baģka bir Ģey yapması gerekmez. Yani C nin o anki çalıģma durumunu B olarak kaydetmek yerine, B nin kaydedilen eski durumun C ya aktarmak, depolanan bilgi içinde uygun değiģiklik yapmak mümkündür. C bittiği zaman, doğrudan A prosedürü tarafından çağrılmıģ gibi olacaktır. B prosedürünün C yi çağırmak yerine, kendisini iģlemin en son adımı olarak çağırdığını düģünelim. B prosedürü yine B yi çağırdığı zaman, çağrıyı yapan B nin yığın bilgisi, çağrılan B nin yığın bilgisi ile yer değiģtirilmelidir. Bu ise çok basit bir iģlemden yani argümanların yeni değerleri almasından ibarettir. Daha sonra iģlem, prosedürün baģ kısmına gider. Prosedürel olarak bu olay bir döngüdeki kontrol değerlerinin yenilenmesine benzer. Bu iģlemlere sondan rekursiyon optimizasyonu veya son-çağrı optimizasyonu adı verilmektedir Sondan Rekursiyonun Kullanımı Prologda bir prosedürün baģka bir prosedürü kendisinin en son adımı olarak çağırmasının ne anlama geldi konusu incelenecektir. 79

90 1. Çağrı, cümlenin en son alt hedefidir. 2. Bu cümlenin ilk kısımlarında geriye dönüģ noktaları yoktur. AĢağıdaki örnek bu iki Ģartı sağlamaktadır: sayac(sayi):- write(sayi), nl, yeni_sayi=sayi+1, sayac(yeni_sayi). ĠĢte bu prosedür sondan rekursif bir prosedürdür ve hafızada yeni bir yığına neden olmaksızın kendisini çağırır. Dolayısıyla hafızayı tüketmez. Bu programa GOAL sayac(0) değeri verilse, 0 ile baģlayan tam sayılar yazılmaya baģlanır ve iģlem bitmez. Örnek: PREDICATES sayac(ulong) CLAUSES sayac(sayi):- write('\r',sayi), Yeni_sayi=Sayi+1, sayac(yeni_sayi). GOAL nl, sayac(0). Bu programa GOAL sayac(0) ile çalıģtırılırsa, 0 dan baģlamak üzere tam sayılar yazılmaya baģlanır ve iģlem bitmez Sondan Rekursiyonu Engelleme 1. Eğer rekursiv çağrı en son adım değilse, prosedür sondan rekursiv değildir. Örneğin; PREDICATES rakam_yaz(ulong) CLAUSES rakam_yaz(sayi):- write('\r', Sayi), Yeni_sayi=Sayi+1, 80

91 rakam_yaz(yeni_sayi), nl. Goal nl, rakam_yaz(0). Rakam_say prosedürü kendisini çağırdında, kontrolün yeniden rakam_say(sayi) dönmesi için hafızada bir yığın kaydedilir. Çünkü son alt hedef nl dir ve bunun iģleme girmesi gerekir. Dolayısıyla döngü bir süre sonra hata mesajı vererek durur. 2. Sondan rekursiyonu engellemenin bir diğer yolu da rekursiyonun yapıldığı anda, geriye henüz denenmemiģ bir alternatifin kalmasıdır. Bu durumda prosedürün son durumunun kaydedilmesi gerekir. Çünkü rekürsiv çağrının baģarısız olması durumunda çağrıyı yapan prosedürün geriye gidip denenmemiģ bir alternatifi deneyebilmesi gerekir. Örnek: Clauses rakam_yaz(sayi):- write('\r', Sayi), Yeni_sayi=Sayi+1, rakam_yaz(yeni_sayi). rakam_yaz(sayi):- Sayi<0, write( Sayi sıfırdan küçüktür. ). GOAL rakam_yaz(0). Burada rakam_yaz cümlesi, ikinci cümle denenmeden önce kendisini çağırır. Program yine bir süre sonra hafıza tükenmesinden dolayı durur. 1. DenenmemiĢ alternatifin rekursiv prosedürün kendisi için ayrı bir cümle olması gerekmez. Rekürsiv prosedürün çağırdığı baģka bir cümlede bir alternatif de olabilir. Örnek: rakam_yaz(sayi):- write('\r', Sayi), Yeni_sayi=Sayi+1, Kontrol_et(Yeni_sayi). rakam_yaz(yeni_sayi). Kontrol_et (Z):-Z>=0. Kontrol_et (Z):- Z<0. 81

92 Sayi değiģkeninin değeri normalde pozitiftir. Bu durumda rakam_yaz her ne zaman kendisini çağırsa, kontrol_et yükleminin ilki doğrulanır, fakat ikinci kontrol_et yüklemin henüz doğrulanmamıģ durumdadır. Bu yüzden rakam_yaz yüklemi, geriye dönüģ iģlemi sırasında kontrol etmek üzere yığın bölgesine bir kopya almak zorundadır. PREDICATES yanlis_sayac1(long) yanlis_sayac2(long) yanlis_sayac3(long) kontrol_et(long) CLAUSES /* Rakam_yaz: Rekursiv çağrı son adım değildir.*/ yanlis_sayac1(sayi):- write ('\r', Sayi), Yeni_sayi=Sayi+1, yanlis_sayac1(yeni_sayi), nl. /* Rakam_yaz2: Rekursiv çağrı yapıldığı anda henüz denenmemiģ bir clause var.*/ yanlis_sayac2(sayi):- write ('\r', Sayi), Yeni_sayi=Sayi+1, yanlis_sayac2(yeni_sayi). yanlis_sayac2(sayi):- Sayi<0, write ("Sayı negatiftir."). /* Rakam_yaz3: Rekursiv çağrıdan önce çağrılan yüklemde denenmemiģ bir alternatif var.*/ yanlis_sayac3(sayi):- write ('\r', Sayi), Yeni_sayi=Sayi+1, kontrol_et(yeni_sayi), yanlis_sayac3(yeni_sayi). 82

93 kontrol_et(z):- Z>=0. kontrol_et(z):- Z<0. GOAL yanlis_sayac1(1458) Rekursiyonda Cut Kullanımı Bir prosedürün sondan rekürsiyonlu olup olmadığından kesin olarak emin olunamayacağı düģünülebilir. Rekursiv olan çağrıyı, son cümleciğin en son alt hedefi yaparak, bu problemi çözmek mümkündür. Fakat yine de hedef cümlesinin çağıracağı diğer prosedürler arasında denenmemiģ baģka bir alternatif olmadığını nasıl garantiye alabiliriz? Bunu garantiye almak gerekmez, çünkü! yani Cut komutunu kullanarak bulunabilecek bütün alternatiflerin önünü kesmek mümkündür. Cut komutunun anlamı Ģöyleydi. Goal cümleciği ile belirlenen yükleme uygun çözüm ararken, gelinen nokta bizim aradığımız noktadır. Artık öteye gitmeye gerek bulunmamaktadır. Alternatifler de ortadan kalktığı için, artık hafızada yığın oluģturmaya gerek kalmaz. Yukarıdaki örnekte görülen rakam_say cümlesini, Ģöyle düzeltmek mümkündür (ĠĢlemdeki ismini değiģtirelim): Cut_sayaci3(Sayi):- Write ( \r, Sayi), Yeni_sayi=sayi+1, Kontrol_et(Yeni_sayi),!, cut_sayaci3(yeni_sayi). Cut komutu yanlis_sayac2 cümleciğinde aynı Ģekilde etkili olur. Çünkü testi negatife düģürüp ikinci cümlecikten birinciye taģır. Cut_sayaci2(Sayi):- Sayi>=0,!, Write ( \r, Sayi), Yeni_sayi=Sayi+1, cut_sayaci2(yeni_sayi). Cut_sayaci2(Sayi):- write ( Sayi negatiftir. ). 83

94 Cut komutunu non-deterministic olan, yani birden fazla çözüm sağlayan yüklemlerle çalıģırken, alınan bilginin yeterli olduğuna inanıldığı anda rahatlıkla kullanılabilir. Aynı Ģey yanlis_sayac3 için de geçerlidir. Kontrol_et yüklemi iģaretine bağlı olarak Sayi üzerinde biraz daha iģlem yapılmasını gerektiren bir durumu göstermektedir. Fakat kontrol_et kodu non-deterministic olduğu için Cut komutu iyi bir çözümdür. Kontrol_et yüklemi Ģöyle yazılabilir: Kontrol_et(Z):- Z>=0,!, /* Z yi kullanarak iģlem yapmak*/ Kontrol_et(Z):-... Cut komutu kullanıldığı zaman bilgisayar denenmemiģ bir alternatifin kalmadığına karar verir ve bu yüzden de yığın oluģturma yoluna gitmez. AĢağıdaki programda yanlis_sayac2 ve yanlis_sayac3 ün düzeltilmiģ hali vardır. PREDICATES cut_sayaci2(long) cut_sayaci3(long) nondeterm kontrol_et(long) CLAUSES /* Rekursiv çağrı yapıldığı anda henüz denenmemiģ bir seçenek var*/ cut_sayaci2(sayi):- Sayi>=0,!, write('\r', Sayi), Yeni_sayi=Sayi+1, cut_sayaci2(yeni_sayi). cut_sayaci2(_):- write("sayi negatiftir."). /* Rekursiv çağrıdan önceki cümlecikte henüz denenmemiģ bir seçenek var*/ cut_sayaci3(sayi):- write('\r', Sayi), Yeni_sayi=Sayi+1, kontrol_et(yeni_sayi),!, cut_sayaci3(yeni_sayi). kontrol_et(z):-z>=0. kontrol_et(z):-z<0. 84

95 GOAL cut_sayaci3(214) Argümanların Döngü Değişkeni Olarak Kullanımı Rukursiyon bölümünde verilen bir sayının faktöriyelini hesaplayan bir program geliģtirilmiģti. Bu durum Pascal da Ģöyle ifade edilebilir: P:=1; For I:=1 to N do P:= P*I; FactN:=P; N, faktöriyeli hesaplancak olan sayı, FactN, N sayısının faktöriyeli, I değeri 1 den N e kadar değiģen döngü değiģkeni ve P ise ara sayıların değerlerinin toplandığı değiģkendir. Bu programı Prolog a aktarırken yapılması gereken ilk Ģey, for komutu için daha basit bir döngü kurmak ve her adımda I değiģkenine ne olduğunu daha açık Ģekilde göstermektir. Program while ile, aģağıdaki biçimde yazılır. P:=1; /* P ve I değiģkenlerine ilk değeri ata.*/ I:=1; While I<= N do /* Döngü kontrolü*/ Begin P:=P*I; /*P ve I değiģkenlerine yeni değerleri ata*/ I:=I+1; End; FactN:=P; /* Sayının Faktöriyelini Yaz..*/ Aynı program Prolog ile aģağıdaki gibi yazılır. PREDICATES faktoriyel(unsigned, real) carpanlarin_faktoriyeli(unsigned, long, unsigned, long) CLAUSES faktoriyel(sayi, Sayinin_Faktoriyeli):- carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, 1, 1). carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, I,P):- I<=Sayi,!, 85

96 Yeni_P=P*I, Yeni_I=I+1, carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, Yeni_I, Yeni_P). carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, I, P):- I>Sayi, Sayinin_faktoriyeli=P. GOAL faktoriyel(5, Sayinin_Faktoriyeli). Programın ayrıntıları aģağıda verilmiģtir. Faktoriyel cümleciğinin Sayi ve Sayinin_Faktoriyeli olmak üzere iki değiģkeni vardır. Bunlardan sayı, faktöriyeli bulunacak sayı, diğeri ise bu sayının faktöriyelidir. Rekursiyon iģlemi aslında carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, I, P) cümlesinden meydana gelir. Bu cümledeki 4 değiģkenin bir adımdan diğerine aktarılması zorunludur. Bu yüzden faktoriyel sadece carpanlarin_faktoriyeli yüklemini harekete geçirir ve sayı, sayının faktöriyeli, I ve P nin ilk değerlerini buraya aktarır. Böylece faktoriyel(sayi, Sayinin_Faktoriyeli):- carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, 1, 1). sayesinde I ve P değiģkenleri ilk değerlerini almıģ olurlar. Burada dikkat çeken Ģey, faktoriyel yükleminin hiçbir değeri olmayan Sayinin_faktoriyeli değerini carpanlarin_faktoriyeli yüklemindeki sayinin_faktoriyeli değiģkenine aktarmasıdır. Prologun yaptığı tek Ģey, iki cümlede bulunan Sayinin_faktoriyeli değiģkenlerini eģleģtirmektir. Aynı Ģey carpanlarin_faktoriyel i yüklemindeki sayinin_faktoriyeli değiģkeninin rekursiv çağrı esnasında kendisine atanmasında da olur. Son aģamada ise Sayinin_faktoriyeli bir değer alacaktır. Bu değeri aldığı zaman daha önceki bütün sayinin_faktoriyeli değiģkeni aynı değeri alır. Gerçekte ise sayinin_faktoriyeli değiģkeninin bir değeri vardır. Çünkü Sayinin_faktoriyeli değiģkeni, ikinci cümledeki carpanlarin_faktoriyeli cümlesinden önce hiçbir zaman gerçek anlamda kullanılmaz. ġimdi carpanlarin_faktoriyeli yüklemine gelelim. Bu yüklem, döngünün devam Ģartı olan I sayısının Sayi dan az veya eģit olup olmadığını kontrol eder. Daha sonra Yeni_I ve Yeni_P değerleriyle kendisini rekursiv olarak çağırır. Burada Prolog un baģka bir özelliği ortaya çıkmaktadır. Diğer dillerin çoğunda mevcut olan 86

97 P=P+1 Ģeklindeki bir ifade Prolog da yanlıģtır. Bu yüzden Prolog da bir değiģkenin değerini değiģtirmek mümkün değildir. Bunun yerine Yeni_P=P+1 Ģeklinde bir ifade kullanmak gerekir. Bu durumda ilk cümlecik carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, I,P):- I<=Sayi,!, Yeni_P=P*I, Yeni_I=I+1, carpanlarin_faktoriyeli(sayi, Sayinin_Faktoriyeli, Yeni_I, Yeni_P). Ģeklinde yazılabilir. Buradaki Cut komutu, cümlecik yüklemde en sonda olmasa da, son çağrı optimizasyonuna imkan tanır. Zamanla I değiģkeninin değeri Sayi değiģkeninin değerine geçer. Bu durumda iģlem P nin o anki değerini sayinin_faktoriyeli ile eģleģtirir ve rekursiyonu bitirir. Bu nokta ikinci cümlede, yani birinci cümledeki I<=Sayi testinin yanlıģ çıktığı zaman meydana gelecektir. carpanlarin_faktoriyeli(sayi, Sayinin_faktoriyeli, I, P):- I>Sayi, sayinin_faktoriyeli=p. haline dönüģür. Sayinin_faktoriyeli=P ifadesinin ayrı bir satırda olması gerekmez. Çünkü sayinin_faktoriyeli değiģkeninin yerine P değiģkenini yazarak değer ataması yapılabilir. Ayrıca I>Sayi testi de gereksizdir, çünkü bunun tersi zaten birinci cümlede denenmiģ olmaktadır. Bunun son hali: carpanlarin_faktoriyeli(_, Sayinin_faktoriyeli,_, Sayinin_Faktoriyeli) olur. PREDICATES faktoriyel(unsigned,real) faktoriyel(unsigned,real,unsigned,real) CLAUSES faktoriyel(sayi, Sayinin_faktoriyeli):- faktoriyel(sayi, Sayinin_faktoriyeli,1,1). faktoriyel(sayi, Sayinin_faktoriyeli, Sayi, Sayinin_faktoriyeli):-!. faktoriyel(sayi, Sayinin_faktoriyeli,I,P):- Yeni_I = I+1, 87

98 Yeni_P = P*Yeni_I, faktoriyel(sayi, Sayinin_faktoriyeli, Yeni_I, Yeni_P). GOAL faktoriyel(12, Sayinin_Faktoriyeli) Rekursiv Veri Yapıları Sadece kurallar değil, aynı zamanda veri yapıları da rekursiv olabilir. Prolog bu tür yapıların kullanılmasına imkan tanıyan yaygın kullanılan tek programlama dilidir. Bir veri türü, kendisi gibi yapıları içeren baģka yapıların kullanımına izin veriyorsa, bu tür veri tiplerine rekursiv denir. En temel rekursiv veri türü listelerdir. Fakat ilk bakıģta rekursiv yapıda oldukları belli olmaz. ġimdi rekursiv olan bir veri türü tanımlayıp, bunu oldukça hızlı bir sıralama programında kullanılması gösterilecektir. Bu veri türünün yapısı aģağıda ağaç yapısında verilmiģtir. Görüldüğü gibi Ali ve AyĢe ile gösterilen her bir dal kendi içinde ayrıca alt dallara ayrılmıģtır. Bundan dolayı da bu tür bir yapı rekursiv olarak adlandırılır. Emine Ali Ayşe Hasan Fatma Fuat Leyla ġekil 6.1. Aile Fertlerinin ġecere Olarak Gösterilmesi 6.9. Ağaç Biçimindeki Veri Türleri Rekursiv veri türleri, ALGOL60 dilinden Pascal dilini çıkaran Niklaus Wirth tarafından popüler hale getirilmiģtir. Bu veri tiplerini Pascal da kullanmamıģ, fakat faydalarına değinmiģtir. 88

99 Visual Prolog, otomatik olarak oluģturulup, pointerlar içereren gerçek rekursiv tip tanımlara imkan tanır. Örneğin aģağıdaki biçimde bir ağaç yapısı tanımlamak mümkündür. Domains Agac_yapisi= agac(string, agac_yapisi, agac_yapisi) Bu ifade agac isimli bir operatör tanımlandığını, bunun da biri string, ikisi ayrıca ağac yapısında, toplam üç değiģkeninin olduğunu gösterir. Ağaç yapısındaki hiçbir veri türü sonsuza kadar gidemeyeceği, rekursiyonu da bitirmek mümkün olmadığı için bu ifade tam olarak doğru değildir. Örneğin bazı hücrelerin diğer hücrelerle bağlantıları yoktur. Prolog da ağaç yapısındaki bir veri yapısında iki tip operatör tanımlanır. Bunlar üç ayrı argümanı olan agac veya hiçbir argümanı olmayan bos operatörleridir. Domains Agac_yapisi= agac(string, agac_yapisi, agac_yapisi); bos Yukarıdaki agac ve bos adındaki yüklemlerin Prolog da önceden tanımlı bir anlamları yoktur ve programcı bunların yerine istediği baģka isimleri kullanabilir. ġimdi ġekil 6.1 de gösterilen tablonun Prolog da nasıl ifade edilebileceği incelenecektir. agac("emine", agac("ali", agac("hasan", bos, bos) agac("fatma", bos, bos)) agac("ayģe", agac("fuat", bos, bos) agac("leyla", bos, bos))) Bir Ağaç Yapısında Tarama Yapma Ağaç Ģeklindeki yapılarda yoğun olarak yapılan iģlem, ya bütün hücreleri incelemek ve hücreleri bir Ģekilde iģlemek veya belirli bir değeri aramak ve bütün değerleri toplamaktır. Buna bir ağacı taramak adı verilmektedir. Bunun en temel algoritmalarından biri Ģudur: 2. Eğer ağaç boģ ise hiçbir Ģey yapma 3. Eğer dolu ise, o anki noktayı incele, buradan soldaki alt dala geç ve daha sonra sağdaki alt dalı incele. Algoritma da tıpkı ağaç yapısı gibi rekursivdir. Soldaki ve sağdaki ağaç yapılarını orijinal ağaç gibi inceler. Prolog bunu iki cümlecik ile ifade eder, biri boģ diğeri de dolu ağaç içindir. 89

100 incele(bos) incele(agac(a, B, C)):- incele(a), incele(b), incele(c). AĢağıdaki ağaç tarama algoritması aşağıya-doğru-arama olarak bilinir. Çünkü Prolog her dalda mümkün olduğu kadar derinlemesine gider, bu dalın sonuna ulaģtığı anda geriye döner ve baģka bir dalı incelemeye baģlar. (ġekil 6.2). 1 2 Emine Ali 5 Ayşe 3 6 Hasan Fatma Fuat Leyla 4 7 ġekil 6.2. ġekil 6.1 deki ağaç yapısında Aşağıya-Doğru-Arama metodunun uygulanması. Prologun yukarıdaki ağacı nasıl tarayacağı yukarıda belirtilmiģtir. AĢağıdaki program, ağaç yapısını tarayarak ağacın her elemanını ekranda görüntülenir. DOMAINS agac_yapisi=agac(string, agac_yapisi, agac_yapisi); bos_dal PREDICATES agaci_tara(agac_yapisi) CLAUSES agaci_tara(bos_dal). agaci_tara(agac(isim, Sol, Sag)):- write(isim, '\n'), agaci_tara(sol), agaci_tara(sag). GOAL 90

101 agaci_tara(agac("emine", agac("ali", agac("hasan", bos_dal, bos_dal), agac("fatma", bos_dal, bos_dal)), agac("ayģe", agac("fuat", bos_dal, bos_dal), agac("leyla", bos_dal, bos_dal)))). Programı yazıp çalıģtırılırsa ekranda Ģunlar görülür. Emine Ali Hasan Fatma AyĢe Fuat Leyla yes aşağıya-doğru-arama Prolog un bir veri tabanını tararken kullandığı yönteme çok benzer. Bu tarama esnasında cümlecikler ağaç Ģeklinde düzenlenir ve her bir dal ayrı ayrı incelenerek sorgu baģarısız oluncaya kadar iģleme devam edilir Bir Ağaç Oluşturmak Ağaç biçiminde bir yapı oluģturmanın bir yolu operatörlerden ve argümanlardan oluģan iç içe geçmeli bir yapı yazmaktır. Prolog, hesaplama yaparak elde ettiği değerlerden bir ağaç oluģturabilir. Her bir adımda, argümanların eģleģtirilmesiyle boģ alt dalın içine boģ olmayan bir dal yerleģtirilir. Basit verileri kullanarak bir hücreli bir ağaç oluģturmak çok basittir. agac_olustur(sayi, agac(sayi, bos_dal, bos_dal)). Yukarıdaki satır Prolog için Eğer Sayi bir sayı ise, agac(sayi, bos_dal, bos_dal) tek hücreli bir ağaç olup veri olarak bu sayıyı içerir anlamına gelir. Ağaç yapısı oluģturmak da en az bu kadar basittir. Örneğin sola_yerlestir(sayi, agac(a, _, B), agac(a, Sayi, B)). Prosedürü üç argümandan oluģmuģtur. Ġlk ağacı, ikinci ağacın alt dalı olarak alır ve üçüncü ağacı da sonuç olarak verir. Yapılan tek Ģey ise, sadece argümanları bire bir eģleģtirmektir. Örneğin agac( Ali, bos_dal, bos_dal) Ģeklindeki bir yapıyı 91

102 agac( Emine, bos_dal, bos_dal) yapısının sol alt dalı olarak yerleģtirilmek istenirse, yazılması gereken tek Ģey Ģu hedefi çalıģtırmaktır. sola_yerlestir(agac( Ali, bos_dal, bos_dal), agac( Emine, bos_dal, bos_dal), T). T nin değeri agac( Emine, agac( Ali, bos_dal, bos_dal), bos_dal) olur. AĢağıdaki örnekte bu teknik gösterilmiģtir. DOMAINS agac_yapisi = agac(string,agac_yapisi,agac_yapisi); bos_dal() PREDICATES agac_olustur(string,agac_yapisi) sola_yerlestir(agac_yapisi,agac_yapisi,agac_yapisi) saga_yerlestir(agac_yapisi, agac_yapisi, agac_yapisi) basla CLAUSES agac_olustur(a,agac(a,bos_dal,bos_dal)). sola_yerlestir(x,agac(a,_,b),agac(a,x,b)). saga_yerlestir(x,agac(a,b,_),agac(a,b,x)). basla:- %Tek daldan oluģan ağaçları oluģturalım agac_olustur("hasan",ha), agac_olustur("fatma",fa), agac_olustur("ali",al), agac_olustur("fuat",fu), agac_olustur("leyla",le), agac_olustur("ayse",ay), agac_olustur("emine",em), %dalları birleģtirelim sola_yerlestir(ha, Al, Al2), saga_yerlestir(fa, Al2, Al3), sola_yerlestir(fu, Ay, Ay2), saga_yerlestir(le, Ay2, Ay3), sola_yerlestir(al3, Em, Em2), 92

103 saga_yerlestir(ay3, Em2, Em3), %sonucu göster write(em3,'\n'). GOAL basla. Program yazılıp çalıģtırılınca ekranda Ģu sonuç görüntülenir. agac("emine",agac("ali",agac("hasan",bos_dal,bos_dal),agac("fatma",bos_dal,b os_dal)),agac("ayse",agac("fuat",bos_dal,bos_dal),agac("leyla",bos_dal,bos_dal))) yes Prolog da bir değiģken herhangi bir değeri aldıktan sonra, artık bu değeri değiģtirmenin bir yolu yoktur. Bundan dolayı yukarıdaki örnekte çok sayıda değiģken ismi kullanılmıģtır. Her yeni değer oluģtuğunda, yeni bir değiģken tanımlamamız gerekir Binary Arama Ağacı ġimdiye kadar ağaç yapısı, bir ağaç ve elemanları arasındaki iliģkileri göstermek için kullanıldı. Temel amaç bu olsaydı, bunun yerine cümleciklerle ifade edilen olgular kullanmak mümkün olurdu. Oysa ağaç yapısının baģka kullanımları da vardır. Ağaç yapılarını kullanarak veri saklamak ve istenildiğinde bu değerleri bulmak çok kolaydır. Bu maksatla oluģturulan ağaç yapısına arama ağacı adı verilir. Programcı açısından buna liste veya array tipindeki verilere bir alternatif gözüyle bakılabilir. Basit bir ağaç yapısını tararken, öncelikle o an içinde bulunulan hücreye, daha sonra bu hücrenin solu ve sağına, belirli bir değeri ararken, bir ağaç yapısındaki bütün hücrelere bakılması gerekebilir. ĠĢte binary arama ağacı, herhangi bir hücreye bakarak aranan bir değerin hangi alt dalda bulunacağını tahmin edebilecek Ģekilde tasarlanır. Bunun için veri parçaları arasında ne tür sıralama olacağının (Örneğin alfabetik veya sayısal sıralama) tanımlanması gerekir. Sol taraftaki alt dalda bulunan veri, o an içinde bulunulan hücredeki veriden önce gelir ve sağ taraftan devam edilir. AĢağıdaki akıģ Ģemasını inceleyim. 93

104 Emine Ali Ayşe Hasan Fatma Fuat Leyla Ġsmail Fatih Haydar ġekil 6.3. Binary tarama yapısı Farklı sırada yerleģtirilen aynı isimlerin farklı bir ağaç Ģeması oluģturur. Ayrıca, Ģemada 10 isim olmasına rağmen, bunlardan herhangi biri en fazla 5 adımda bulunabilir. Binary bir tarama yapısında bir hücreye bakarken, geriye kalan hücrelerin yarısını elimine edilir. Bu yüzden tarama çok çabuk ilerler. Bir Binary Tarama Yapısındaki bir maddeyi bulmak için gereken zaman ortalama olarak log2n dir. Bir ağaç oluģtururken, iģe önce boģ bir ağaç ile baģlanır. Daha sonra diğer parçalar teker teker ilave edilir. Bir madde ilave etmek için gereken prosedür, bir maddeyi aramak için gereken ile tamamen aynıdır. 1. Eğer içinde bulunulan nokta boģ bir ağaç ise, buraya bir madde yerleģtir. 2. Değilse, buraya yerleģtirilecek maddeyi, orada saklı olan madde ile karģılaģtır. KarĢılaĢtırmanın sonucuna göre, maddeyi sol veya sağ alt dala yerleģtir. Bunun için Prolog a 3 cümle gerekir. Ġlk cümle: yerlestir(yeni_madde, bos, agac(yeni_madde, bos, bos):-!. Bunu konuģma diline Yeni_madde yi bos olan yere yerleģtirmenin sonucu agac(yeni_madde, bos, bos) olur. Buradaki Cut komutu, cümlenin uygun olması durumunda baģka bir cümlenin denenmemesi içindir. Ġkinci ve üçüncü cümleler boģ yerlere yerleģtirmek için kullanılır. 94

105 Yerlestir(Yeni_Madde, bos, agac(eleman, Sol, Sag), agac(eleman, Yeni_Sol, Sag):- Yeni_Madde<Eleman,!, yerlestir(eleman, Sol, Yeni_Sol). Yerlestir(Yeni_Madde, bos, agac(eleman, Sol, Sag), agac(eleman, Sol, Yeni_Sag):- yerlestir(yeni_madde, Sag, Yeni_Sag). Eğer Yeni_Madde<Eleman olursa, değer sol alt dala yerleģtirilir; aksi takdirde sağ alt dala yerleģtirilir Ağaca Bağlı Sıralama Ağaç yapısı oluģturulduktan sonra, bu yapı içerisindeki bütün maddeleri alfabetik olarak elde etmek çok kolaydır. Kullanılacak algoritma aģağıya-doğru-tarama yönteminin değiģik bir Ģeklidir: 1. Eğer ağaç boģ ise hiçbir Ģey yapma. 2. Değilse, sol tarafta olan bütün değerleri, daha sonra o anki elemanı, sonra da sağ taraftaki bütün elemanları al. Prolog diliyle, aģağıdaki Ģekilde ifade edilir. Hepsini_al(bos). Hepsini_al(agac(Madde, Sol, Sag)):- Hepsini_al(Sol), isleme_devam_et(madde), hepsini_al(sag). Örnek: AĢağıdaki programda ekrandan yazılan karakterler, daha sonra alfabetik sırayla görüntülenmektedir. Karakterler kendi aralarında büyük veya küçük olmalarına göre de sıralanmaktadır. Programda kullanılan bazı yüklemler daha sonra incelenecektir. DOMAINS karakter_dizisi = agac(char, karakter_dizisi, karakter_dizisi); son PREDICATES nondeterm basla(karakter_dizisi) eylem(char, karakter_dizisi, karakter_dizisi) agac_olustur(karakter_dizisi, karakter_dizisi) yerlestir(char, karakter_dizisi, karakter_dizisi) agaci_yaz(karakter_dizisi) nondeterm tekrar 95

106 CLAUSES basla(agac):- tekrar,nl, write("***********************"),nl, write("agaci guncelleme : 1 \n"), write("agaci incelemek : 2 \n"), write("programi bitirmek : 7 \n"), write("***********************"),nl, write("tercihiniz > "), readchar(x),nl, eylem(x, Agac, Yeni_agac), basla(yeni_agac). eylem('1',agac,yeni_agac):- write("istediginiz karakterleri yaziniz, bitirmek için # karakterini giriniz: "),nl, agac_olustur(agac, Yeni_agac). eylem('2',agac,agac):- agaci_yaz(agac), write("\ndevam etmek için bir tusa basiniz.."), readchar(_),nl. eylem('7', _, son):- exit. agac_olustur(agac, Yeni_agac):- readchar(c), C<>'#',!, write(c, " "), yerlestir(c, Agac, Gecici_agac), agac_olustur(gecici_agac, Yeni_agac). agac_olustur(agac, Agac). yerlestir(yeni,son,agac(yeni,son,son)):-!. yerlestir(yeni,agac(eleman,sol,sag),agac(eleman,yeni_sol,sag)):- Yeni<Eleman,!, 96

107 yerlestir(yeni,sol,yeni_sol). yerlestir(yeni,agac(eleman,sol,sag),agac(eleman,sol,yeni_sag)):- yerlestir(yeni,sag,yeni_sag). agaci_yaz(son). agaci_yaz(agac(madde,sol,sag)):- agaci_yaz(sol), write(madde, " "), agaci_yaz(sag). tekrar. tekrar:-tekrar. GOAL write("yazilan karakterleri siralama "),nl, basla(son). 97

108 7. LİSTELER VE REKÜRSİYON Çok sayıda eleman içeren nesnelerle çalıģmak, yani liste iģlemek, Prolog un güçlü yönlerinden biridir. Daha önce kısaca anlatılan bu konu, burada daha ayrıntılı olarak ele alınacaktır. Listelerin ne oldukları, nasıl tanımlandıkları ve uygulama programlarında nasıl kullanılabilecekleri hakkında bazı örnekler çözülecektir. Liste iģleme metoduna rekursiv ve prosedürel yönlerden yaklaģırken, Prolog un çok önemli yüklemlerinden olan member ve append üzerinde durulacaktır. Daha sonra verilen dahili bir sorgu için mümkün olan bütün çözümleri bulan ve görüntüleyen findall standart yüklemini incelenecektir Listeler Bir listenin, çok sayıda nesne içeren bir nesne olduğu bilinmektedir. Prolog daki bir liste, diğer dillerdeki dizilere(array) karģılık gelir. Listelerin dizilerden en önemli farkı, bir diziyi kullanmadan önce bu dizide kaç tane eleman olacağını önceden belirtmenin gerekmemesidir. Eğer birleģtirilecek nesnelerin sayısı önceden biliniyorsa, bunlar tek bir bileģik veri yapısının argümanı haline getirilebilir. Elemanları a, b ve c olan bir liste [a, b, c] Ģeklinde ifade edilir. Burada a, b ve c birer elemandır ve bu elemanlar bir virgül ile ayrılarak [...] arasında yazılırlar. Örnekler: [araba, ev, televizyon] [ Mahmut AKSOY, Sefer KAÇAR, Mahmut ÜSTÜNDAĞ ] Liste Tanımlanması Liste tanımları programların domains bölümlerinde yapılır. Tamsayılardan oluģan bir liste Domains tamsayilar_listesi = integer* 98

109 Ģeklinde tanımlanır. Burada * tamsayilar_listesi argümanının tamsayılardan oluģan bir liste olduğunu gösterir. Liste tanımlarken, listeye verilen ismin Prolog da hiçbir önemi yoktur. Önemli olan Ģey * ile tanımlı kelimenin bir listeyi temsil ettiğinin belirtilmesidir. Bir listenin elemanları herhangi bir Ģey olabileceği gibi, baģka listeler de eleman olarak kullanılabilirler. Dikkat edilmesi gereken Ģey, bir listedeki elemanların tamamının aynı tipde olması, bu elemanların tipinin de ayrıca tanımlanmasıdır. Örnek: Domains Benim_listem = elemanlarim* elemanlarim= integer /*real, symbol vs. olabilir.*/ Fakat bir listede bulunan standart tiplerin karıģık olarak kullanılması mümkün değildir. Örneğin benim_listem = elemanlarim* elemanlarim= integer; real; symbol tanımlaması yanlıģtır. Fakat integer, real ve symbol tiplerinden oluģan bir liste tanımlamak için farklı operatörler kullanılabilir: benim_listem = elemanlarim* elemanlarim= tamsayi(integer); reel_sayi(real); karakter(symbol) Bir Listenin Parçaları: Baş ve Kuyruk Bir liste iki kısımdan oluģur. Bunlar listenin ilk elemanının oluģturduğu baş ve geriye kalan elemanların oluģturduğu kuyruk kısmıdır. Yani bir listenin baģ kısmı daima sadece tek eleman, kuyruk kısmı ise daima ayrı bir listeden ibarettir. Örnek: [a, b, c] listesinde a listenin baģı; b ve c ise kuyruk kısmıdır. [a] listesinde listenin baģı a olur. [], yani boģ bir liste de listenin kuyruk kısmıdır. BoĢ bir listeyi baģ ve kuyruk olarak ayırmak mümkün değildir. Dolayısıyla bir listenin kuyruk kısmının her seferinde ilk elemanı alınırsa, sonuçta boģ bir listeye ulaģılır. Bu yüzden listeleri bileģik nesneler gibi ağaç yapısında görmek mümkündür. Örneğin [a, b, c, d] listesine bu iģlem aģağıdaki gibi uygulanır. 99

110 liste / \ a liste / \ b liste / \ c liste / \ d [ ] Burada [a] ile a birbirinin aynısı değildir. Çünkü a tek baģına bir eleman iken [a] tam bir bileģik yapıdadır. Çünkü [a] liste / \ a [ ] Ģeklinde ifade edilir Listelerin İşlenmesi Prologda bir listenin elemanlarını virgüle ayırmak yerine, baģ ve kuyruk kısımlarını daha belirgin olarak ifade etmek için sadece baģ ve kuyruk kısımları dikey çizgi ile ayrılır. Örneğin: [a, b, c] yerine [a [b, c]] veya benzer Ģekilde devam edersek [a [b [c]]] biçimi kullanılabilir. Burada [c] listesini de baģ ve kuyruk olarak ayırırsak, [a [b [c []]]] olur. Tablo 7.2. Listelerin baģ ve kuyruk halinde gösterilmeleri Liste Baş Kuyruk ['a', 'b', 'c'] 'a' ['b', 'c'] [ 'a' ] 'a' [] /* BoĢ liste*/ [ ] Tanımsız Tanımsız [[1, 2, 3], [2, 3, 4], []] [1, 2, 3] [[2, 3, 4], []] 100

111 Tablo 7.3: Liste eģleģtirme örnekleri Liste 1 Liste 2 Değişken eşleştirme [X, Y, Z] [kedi, eti, yedi] X=kedi, Y=eti, Z=yedi [7] [X Y] X=7, Y=[] [1, 2, 3, 4] [X, Y Z] X=1, Y=2, Z=[3,4] [1, 2] [3 X] YanlıĢ (Neden?) Listelerin Kullanılması Listeler gerçek anlamda rekursiv bileģik veri yapıları olduklarından bunların kullanılmaları için rekursiv algoritmaların kullanılması gerekir. Liste iģlemesinin en temel yöntemi, listenin son elemanına ulaģıncaya kadar listenin her elemanını incelemektir. Bu tür iģlemde kullanılması gereken algoritmalar genelde iki cümleden oluģurlar. Bir cümle, baģ ve kuyruk olarak ikiye bölünebilen listeler için, ikincisi ise boģ listeler için kullanılır. Örneğin aģağıdaki programda bir listenin elemanlarını nasıl görüntüleyeceğimizi görelim: DOMAINS benim_listem = string* PREDICATES benim_listemi_yaz(benim_listem) CLAUSES benim_listemi_yaz ([]). /*Liste boģ ise yapılacak bir Ģey yok.*/ benim_listemi_yaz ([Bas Kuyruk]):-write(Bas), nl, benim_listemi_yaz (Kuyruk). GOAL benim_listemi_yaz(["visual", "Prolog", "4.0"]). Bu programdaki benim_listemi_yaz (["Visual", "Prolog", "4.0"] sorgusuyla Bas= Visual, Kuyruk=["Prolog","4.0"] değerlerini alır ve Visual değeri yazılır. Daha sonra benim_listemi_yaz yüklemi rekursiv olduğu için ["Prolog", "4.0"] kısmı yeniden bölünür. Bu kez Bas=Prolog, Kuyruk=4.0 olur ve Prolog değeri görüntülenir. Rekursiv iģlem bir kez daha 4.0 için uygulanır ve bu defa Bas=4.0, Kuyruk=[] olur. Kuyruk kısmı boģ liste olduğundan sadece 4.0 görüntülenir. Rekursiv çağrı bu kez boģ liste için yapılır, fakat listenin BaĢ ve Kuyruk kısımlarının eģleģebilecekleri değer 101

112 olmadığından, program akıģındaki benim_listemi_yaz([]) cümlesi çağrılır ve program bir Ģey yapmadan normal Ģekilde durur. benim_listemi_yaz ([]) Ģeklindeki cümle, programın normal bir biçimde durmasını sağlar Liste Elemanlarının Sayılması Bir listenin kaç elemandan oluģtuğunu nasıl bulabiliriz? Bunun için kullanılması gereken temel mantık Ģudur. Liste boģ [] ise, listedeki toplam eleman sayısı 0 dır. Bunun dıģındaki listelerin eleman sayısı 1+ Kuyruk Uzunluğu ile bulanabilir. Prolog da karģılığı aģağıda verilmiģtir. DOMAINS liste=integer* PREDICATES liste_uzunlugu(liste, integer) CLAUSES liste_uzunlugu([], 0). liste_uzunlugu([_ Kuyruk],Eleman_sayisi):-liste_uzunlugu(Kuyruk, Kuyruk_uzunlugu), Eleman_sayisi=Kuyruk_uzunlugu+1. GOAL liste_uzunlugu([1, 2, 3], Eleman_sayisi). Ġlk cümledeki [_ Kuyruk] boģ olmayan bütün listelerle eģleģebilir. Bizim için önemli olan kısım listenin kuyruk kısmı olduğu için baģ kısmı yerine anonim değiģken kullanılmıģtır. GOAL liste_uzunlugu([1, 2, 3], Eleman_sayisi). sorgusu ikinci cümle ile eģleģir ve Kuyruk=[2, 3] olur. Daha sonraki adım Kuyruk uzunluğunu hesaplamaktır. Bu yapıldığı zaman Kuyruk=2 olur. Uzunluk=kuyruk_uzunluğu+1 olduğundan Uzunluk=3 olur. Liste_uzunlugu yüklemi kendisini çağırarak [2, 3] listesinin uzunluğunu bulur. Bunun için Cümledeki kuyruk=[3] değerini alır. Kuyruk_uzunlugu=Eleman_sayisi değerini alır. 102

113 Her rekursiv cümlenin kendisine ait değiģken kümesi olduğundan, cümledeki kuyruk_uzunlugu ve sorgudaki kuyruk_uzunlugu birbirine karıģmadığı unutulmamalıdır. Bu durumda bütün mesele [3] uzunluğunu bulmaktır. Bu 1 olduğu için buna 1 ilave edilirse [2, 3] için toplam uzunluk 2 olur. [3] listesinin uzunluğu için liste_uzunlugu yüklemi kendisin tekrar çağırır. Bu kez [3] listesinin kuyruk uzunluğu Kuyruk=[] olur. Kuyruk uzunluğunu hesaplamak için ise liste_uzunlugu([], Kuyruk_uzunlugu) ilk cümle ile eģleģir ve Kuyruk_uzunlugu=0 olur. ġimdi bilgisayar bu değere, yani 0 a 1 ilave ederek [3] ün uzunluğunu bulur. Buna 1 ilave ederek [2, 3] ün uzunluğunu bulur. Nihayet buna da 1 ilave ederek [1, 2, 3] listesinin toplam uzunluğunu bulur. ġimdi bu iģlemlerin tamamını sıralayarak konuyu biraz daha netleģtirelim. Liste_uzunlugu([1, 2, 3], Eleman_sayisi1). Liste_uzunlugu([2, 3], Eleman_sayisi2). Liste_uzunlugu([3], Eleman_sayisi3). Liste_uzunlugu([], 0). L3=0+1=1 L2=L3+1=2 L1=L2+1= Sondan Rekursiyona Yeniden Bakış Rekursiv bir çağrı, cümledeki son adım olamayacağı için liste_uzunlugu nun sondan rekursiv olamayacağı bellidir. Bunu sondan rekursiv yapmanın yolu vardır. Burada problem olan Ģey, kuyruk uzunluğu bilinmeden bir listenin toplam uzunluğunun hesaplanamayıģıdır. Yani bu probleme bir çözüm bulunabilirse, liste_uzunlugu yüklemini sondan rekursiv yapmak mümkündür. Bunun için liste_uzunlugu yükleminin üç argümanının olması gerekir. 1. Birincisi, her seferinde kırpılarak sonunda boģ bir liste elde edilecek listenin kendisi. 2. Bir diğeri, liste uzunluğunu saklayacak boģ bir değiģken 103

114 3. Sonuncusu ise 0 ile baģlayan ve her seferinde değerinin 1 arttığı bir sayaç değiģken. Geriye sadece boģ olan liste kaldığı zaman bu sayaç hiçbir değiģkene atanmamıģ olan sonucu alır. DOMAINS liste=integer* PREDICATES liste_uzunlugu(liste, integer, integer) CLAUSES liste_uzunlugu([], Sonuc, Sonuc). liste_uzunlugu([_ Kuyruk], Sonuc, Sayac):- Yeni_sayac=Sayac+1, liste_uzunlugu(kuyruk, Sonuc, Yeni_Sayac). GOAL liste_uzunlugu([1, 2, 3], Uzunluk, 0), write ("Uzunluk =", Uzunluk), nl. Verilen bir listedeki elemanlar üzerinde iģlem yaptıktan sonra bu elemanların yerine hesaplanan elemanlardan oluģan baģka bir liste oluģturmak mümkündür. AĢağıdaki örnekte listenin her elemanını 1 ilave ederek yeni bir liste elde edilmiģtir. DOMAINS liste = integer* PREDICATES yeni_deger_ilave_et(liste, liste) CLAUSES yeni_deger_ilave_et([], []). /* Ġlk Ģart*/ yeni_deger_ilave_et([bas Kuyruk],[Bas1 Kuyruk1]):- /* Bas ve Kuyruk ayrılması*/ Bas1=Bas+1, /* Listenin ilk elemanına 1 ilave et*/ yeni_deger_ilave_et(kuyruk, Kuyruk1). /* elemanı listenin geriye kalanıyla çağır*/ GOAL yeni_deger_ilave_et([1, 2, 3], Yeni_Liste). Yukarıda yapılan iģlemler, sözel olarak aģağadaki Ģekilde yazılır. 104

115 BoĢ bir listenin bütün elemanlarına 1 ilave etmek için sadece baģka bir boģ liste oluģtur. BoĢ olmayan herhangi bir listenin bütün elemanlarına 1 ilave etmek için, listenin baģ kısmına 1 ilave et ve ilave edilen bu değeri yeni listenin baģı olarak al. Daha sonra kuyruk kısmının bütün elemanlarına 1 ilave et ve yeni değerleri de yeni listenin kuyruk kısmı olarak al. Sonucu Yeni_liste olarak ekranda görüntüle. Verilen liste [1, 2, 3] olduğu için: 1. Önce BaĢ ve Kuyruk kısımları ayrılır ve sırasıyla [1] ve [2, 3] olurlar. 2. Sonuç listenin baģ ve kuyruk kısımlarına Bas1 ve Kuyruk1 değerlerini ata. Burada Bas1 ve Kuyruk1 in henüz değer almadığına dikkat edilmelidir. 3. Bas kısmına 1 ilave et ve Bas1 i elde et. 4. Rekursiv olarak Kuyruk kısmındaki bütün elemanlara 1 ilave et ve Kuyruk1 i elde et. Bu yapıldığı zaman Bas1 ve Kuyruk1 kendiliğinden sonuç listesinin Bas ve Kuyruk kısmı olur. Bunları birleģtirmek için ayrı bir operasyon gerekmez. Dolayısıyla rekursiv çağrı gerçekten de prosedürün son adımı durumundadır. Örnek: Bir listedeki sayıları tarayıp negatif olanları eleyen program DOMAINS liste=integer* PREDICATES negatifleri_ele(liste, liste) CLAUSES negatifleri_ele([], []). negatifleri_ele([bas Kuyruk], IslenmisKuyruk):- Bas<0,!, negatifleri_ele(kuyruk, IslenmisKuyruk). negatifleri_ele([bas Kuyruk], [Bas IslenmisKuyruk]):- negatifleri_ele(kuyruk, IslenmisKuyruk). GOAL negatifleri_ele([2, -45, 3, 4, -5, -45], Yeni_Liste). AĢağıdaki yüklem, bir listenin her elemanını baģka bir listeye iki kez aktarmaktadır. 105

116 elemanlari_ikile([], []). elemanlari_ikile([bas Kuyruk], [Bas, Bas Ikilenmis_Kuyruk]):- elemanlari_ikile(kuyruk, Ġkilenmis_Kuyruk) Liste Elemanlığı Ahmet, Mehmet, Hasan ve Nejla isimlerini eleman olarak içeren bir listede, örneğin Ahmet isminin var olup olmadığını öğrenilmek istensin. Yani isim ve bir isim arasında bir iliģki sorgulansın. Bunun için kullanılan bir yüklem vardır. uye(isim, isimlistesi). /*Burada isim listede geçen bir isimdir.*/ DOMAINS isim_listesi = isim* isim = symbol PREDICATES nondeterm uye(isim, isim_listesi) CLAUSES uye(isim, [Isim _]). uye(isim, [_ Kuyruk]):- uye(isim, Kuyruk). GOAL uye(ahmet, [ mehmet, ahmet, hasan, nejla]). Yukarıdaki örnekte önce birinci cümleyi inceleyelim. uye(isim, [Isim _]) cümlesindeki Isim değiģkeni listenin öncelikle baģ kısmında araģtırılır. Eğer eģleģme sağlanırsa üyeliğin var olduğu sonucuna varılır ve olumlu sonuç görüntülenir. Listenin kuyruk kısmı bizi ilgilendirmediği için burada anonim değiģken kullanılmıģtır. Eğer aradığımız isim listenin baģ kısmı ile eģleģmezse bu kez listenin kuyruk kısmını incelemek için ikinci cümle kullanılır Listeleri Birleştirme AĢağıdaki iki cümleyi tekrar inceleyelim. Bu iki cümleye prosedürel ve dekleratif olarak bakmak mümkündür. uye(isim, [Isim _]). uye(isim, [_ Kuyruk]):- uye(isim, Kuyruk). Bu cümlenin dekleratif olarak anlamı Ģudur: 106

117 Eğer cümlenin baģ kısmı Isim değiģkenine eģitse, bu durumda Isim, listenin bir elemanıdır. Bu durum doğru değilse, Isım değiģkeni kuyruk kısmının üyesi ise Isim listenin bir elemanıdır. Prosedürel olarak bu iki cümle Ģöyle yorumlanabilir. Bir listedeki herhangi bir elemanı bulmak için, listenin baģ kısmını; aksi takdirde, bu listenin kuyruk kısmının bir üyesini bulunuz. Bu iki durumu denemek için uye(2, [1, 2, 3, 4]) ve uye[x, [1, 2, 3, 4]) sorgularını kullanınız. Ġlk sorgu, bir durumun doğru olup olmadığını sorgulamak için kullanılırken, ikinci sorgu listenin bütün üyelerini bulmak için kullanılmaktadır Rekursiyona Prosedürel Bir Bakış Bu kısımda bir listeyi baģka bir listeye ekleyen bir yüklem oluģturulacaktır. Ekle yükleminin üç argümanla birlikte tanımlanması gerekir. Ekle(Liste1, Liste2, Liste3) Ekle yüklemi Liste1'i Liste2'ye ilave ederek Liste3'ü elde eder. Eğer Liste1 boģ ise, bu durumda 1. Listeyi 2. Listeye ilave etmek bir Ģeyi değiģtirmez. Yani: Ekle([], Liste2, Liste2). Eğer liste1 boģ değilse, Ekle([Bas Kuyruk1], Liste2, [Bas Kuyruk3]):-ekle (Kuyruk1, Liste2, Kuyruk3]). Liste1 boģ değilse, rekursiv olan yüklem her seferinde bir elemanı Liste3'e transfer eder. Liste1 boģ olduğunda ilk cümle Liste2'yi liste3'ün sonuna ilave eder. Örnek: DOMAINS sayilar=integer* PREDICATES ekle(sayilar, sayilar, sayilar) CLAUSES ekle([], Liste, Liste). ekle([bas Kuyruk1], Liste2, [Bas Kuyruk3]):- ekle (Kuyruk1, Liste2, Kuyruk3). GOAL ekle ([1, 3, 5], [2, 4, 6], Yeni_Liste). 107

118 Yukarıdaki programı sadece birleģtirilen iki listenin sonucunu almak için değil, aynı zamanda sonuç listesini yazıp ilk iki liste için geçerli bütün alternatifleri bulmak için kullanmak mümkündür. Örneğin GOAL ekle (Birinci_Liste, Ikinci_liste, [2, 4, 5, 6]). Denendiğinde toplam 5 çözüm bulunur. Ayrıca GOAL ekle ([3, Ikinci_eleman],Liste_2, [3, 4, 5, 6]) Ģeklindeki bir sorgu ile birinci listenin, örneğin ikinci elemanı ve ikinci listenin tamamını bulmak da mümkündür Bütün Çözümleri Bir Defada Bulma Rekursiyon ve geriye iz sürme iģlemlerini karģılaģtırırken rekursiyonun daha avantajlı olduğu daha önce belirtilmiģti. Bunun nedeni, rekursiyon esnasında argümanlar vasıtasıyla aradaki adımlarda elde edilen verilerin saklanabilmesidir. Öte yandan geriye dönüģ iģlemi bir sorguyu sağlayan bütün çözümleri bulabilirken, rekursiyon bunu yapamaz. Bunun için Prolog'un hazır yüklemlerinden olan findall yüklemi kullanılır. Findall bir sorguyu kendi argümanlarından biri olarak alır ve bu sorgunun bütün çözümlerini tek bir liste altında toplar. Findall yükleminin toplam 3 argümanı vardır. Ġlk değiģken, örneğin Degisken_Ismi, yüklemden listeye aktarılacak değiģkenin hangisi oldugunu gösterir. Ġkinci değiģken, örneğin yeni_yuklem, değerlerin alınacağı yüklemi gösterir. Üçüncü argüman, örneğin Yeni_Degisken, geriye dönüģ iģlemiyle elde edilen değerlerin listesi tutan bir değiģkendir. Yeni_degisken değerlerinin ait olduğu bir tip tanımının kullanıcı tarafından yapılmıģ olması lazımdır. Bir gruptaki yaģ ortalamasını bulan bir program, aģağıdaki Ģekilde yazılabilir. DOMAINS isim, adres = string yas = integer liste = yas* PREDICATES nondeterm kisi(isim, adres, yas) toplam_liste(liste, yas, integer) calistir 108

119 CLAUSES toplam_liste([], 0, 0). toplam_liste([bas Kuyruk], Toplam, N):- toplam_liste(kuyruk, S1, N1), Toplam=Bas+S1, N=1+N1. kisi("oktay DUYMAZ", "Cumhuriyet Cad.", 36). kisi("o.faruk AKKILIÇ", "Nail Bey Mah. ", 30). kisi("hakay TAġDEMĠR", "Firat Cad. No: 17", 28). calistir:- findall(yas, kisi(_,_, Yas), L), toplam_liste(l, Toplam, N), Ortalama=Toplam/N, write("ortalama = ", Ortalama), nl. GOAL calistir. Programdaki findall cümlesi L listesini oluģturarak kisi yükleminden elde edilen bütün yaģları buraya aktarır Bileşik Listeler ġimdiye kadar oluģturulan listelerde daima aynı türden olan elemanlar saklanmıģtır. Listeler tamsayı, symbol vs.den oluģuyordu. Bir liste içerisinde farklı tipte elemanları bir arada yazmak oldukça faydalı olur. Birden fazla tipte olan elemanları bir arada tutmak için özel tanımlamaların yapılması gerekir. Bu da farklı operatörler tanımlamakla olur. Örnek: Domains. Benim_listem = 1(liste); i(integer); c(char); s(string) Liste=benim_listem* [i(2), i(9), 1([s("araba"), s("bilgisayar")]), s("kalem")] Örnek: DOMAINS benim_listem =l(liste); i(integer); c(char); s(string) 109

120 liste=benim_listem* PREDICATES ekle(liste, liste, liste) CLAUSES ekle([], L, L). ekle([x L1], L2, [X L3]):- ekle(l1, L2, L3). GOAL ekle([s(sever), l([s(ahmet), s(deniz)])], [s(ahmet), s(ayse)], Sonuc), write("ilk Liste : ", Sonuc, "\n"), ekle([l([s("bu"), s("bir"), s("listedir.")]), s(test)], [c('c')],sonuc2),nl, write ("Ġkinci Liste: ", Sonuc2,'\n'). 110

121 8. AKIŞ DENETİMİ Bir yüklem içinde değeri bilinen değiģkenlere input (giriģ değiģkenleri), bilinmeyenlere ise output (çıkıģ değiģkenleri) denir. Bu argümanların, input argümanları ise baģlangıç değeri verilerek, output argümanları ise çıktı almak üzere uygun biçimde kullanılmasına akış biçimi denir. Örneğin bir argümanın iki değiģkenle çağrılması durumunda 4 farklı akıģ biçiminden söz edilebilir. (i, i) (i,o) (o,i) (o, o) Programlar derlendiği zaman yüklemlerin global bir akıģ analizi yapılır. Ana sorgu ile baģlayıp bütün programın değerlendirmesi yapılır. Bu esnada programdaki bütün yüklemlere akıģ biçimleri atanmıģ olur. AkıĢ analizi oldukça basittir. Çünkü program yazarken farkında olmadan aynı Ģey tarafımazdan da yapılmaktadır. Örnek: GOAL cursor(r, C), R1=R+1, cursor(r1, C). Cursor yüklemine yapılan ilk çağrıda R ve C değiģkenlerinin hiçbir değeri olmadığı için serbest değiģken durumundadırlar. Dolayısıyla akıģ biçimi cursor(o, o) olur. R1=R+1 ifadesinde R değiģkeninin değeri cursor yükleminden geleceği için, R değiģkenin bağlı olduğu bellidir. Bu çağrıdan sonra R1 değiģkeni değer almıģ olur. Eğer R değiģkeni boģ olsaydı, bu durumda bir hata mesajı görüntülenirdi. Cursor yükleminin son kez çağrılmasında R1 ve C değiģkenlerinin ikisi de önceden çağrıldığı için artık giriģ değiģkenleri olarak iģlem görürler. Yani çağrının akıģ biçimi cursor(i, i) olur. Burada sadece DOS Metin Modu ortamında çalıģan aģağıdaki örnekler irdenelecektir. Predicates ozellik_degistir(integer, Integer) Clauses ozellik_degistir(yeni_ozellik,eski_ozellik):-ozellik(eski_ozellik), ozellik(yeni_ozellik). 111

122 GOAL ozellik_degistir(112, Eski), write("merhaba"), ozellik(eski, write(" millet"). GOAL kısmındaki ilk çağrı ozellik_degistir(i, o) ile yapılır. Burada 112 bilinen, Eski ise bilinmeyen değiģkendir. Bu durumda ozellik_degistir cümlesi Yeni_ozellik değiģkeni ile çağrıldığında bunun değeri belli olduğu için input, Eski_ozellik'in değeri belli olmadığı için output olacaktır. AkıĢ denetçisi ilk alt hedef olan ozellik(eski_ozellik) cümlesine geldiği zaman ozellik yüklemi ozellik(o) akıģ biçimi ile çağrılır. Ozellik yükleminin ikinci çağrılıģı ozellik(i) Ģeklinde olacaktır. Ana sorgudaki ozellik yüklemine yapılan çağrı input olacaktır, çünkü ozellik_degistir yükleminden alınır Bileşik Akış Bir yüklemdeki değiģken bileģik bir nesne ise, akıģ biçimi bileģik bir Ģekilde olabilir. ġimdi aģağıdaki örnekte olduğu gibi, bir ülke hakkında bilgilerin verildiği bir veritabanı düģünelim. Yeni bilgileri rahatlıkla ilave edebilmek için her bilgiyi kendi tipiyle saklamak istenebilir. DOMAINS ulke_bilgileri=alan(string, ulong); nufus(string, ulong);baskent(string, string) PREDICATES nondeterm ulke(ulke_bilgileri) CLAUSES ulke(alan("türkiye",876000)). ulke(nufus("türkiye", )). ulke(baskent("türkiye", "Ankara")). ulke(alan("almanya",840000)). ulke(nufus("almanya", )). ulke(baskent("almanya", "Bohn")). GOAL ulke(alan(ad, Alan)), ulke(nufus(ad, Nuf)). Sorguyu aģağıdaki cümlelerle deneyiniz: ulke (C) (o) ulke(alan(ulke_adi, Alani)) (o,o) 112

123 ulke(nufus("türkiye", Nuf)) (i, o) ulke(baskent("türkiye", "Ankara")) (i) Son örnekteki bütün terimler bilindiği için akıģ biçim düz metindir Yüklemlerin Akış Biçimlerini Tanımlama Yüklemler için uygun bir akıģ biçimi tanımlamak bazen daha güvenlidir. Yüklemlerin sadece özel akıģ biçimleri durumunda geçerli olacağı biliniyorsa, önceden akıģ biçimi tanımlamak faydalıdır. Çünkü bu durumda akıģ denetçisi bu yüklemlerden yanlıģ kullanılanı çok rahatlıkla bulabilir. Tip tanımı yapıldıktan sonra '-' iģareti yazarak akıģ biçimi vermek mümkündür. PREDICATES musteri_bilgi_listesi(string, string, slist) -(i, o, o)(o, i, o) 8.3. Akış Analizini Kontrol Etmek Analiz mekanizması, standart bir yüklemin yanlıģ bir akıģ biçimi ile çağrıldığını tesbit ettiği an hata mesajı verir. Bu hata mesajı, standart yüklemleri çağıran yüklemler tanımladığımız zaman, bunlardan akıģ biçimi anlamsız olanları tesbit etmede bize yardımcı olur. Örnek: C=A+B ifadesinde A ve B serbest değiģken olduğundan, akıģ denetçisi bu yüklem için akıģ biçimi olmadığını bildiren bir hata mesajı verecektir. Bu durumu kontrol etmek için free ve bound standart yüklemleri kullanılır. Ġki sayı arasında toplama yapmak veya toplam ile ilk sayısı verilen bir durumda ikinci sayıyı bulan, bütün akıģ biçimleriyle çağrılabilen topla adında bir yüklem tanımlayalım. Örnek: PREDICATES nondeterm topla(integer, integer, integer) nondeterm sayi(integer) CLAUSES 113

124 topla(x,y,z):- bound(x), bound(y), Z=X+Y. /* (i,i,o) */ topla(x,y,z):- bound(y), bound(z), X=Z-Y. /* (o,i,i) */ topla(x,y,z):- bound(x), bound(z), Y=Z-X. /* (i,o,i) */ topla(x,y,z):- free(x), free(y), bound(z), sayi(x), Y=Z-X. /* (o,o,i) */ topla(x,y,z):- free(x), free(z), bound(y), sayi(x), Z=X+Y. /* (o,i,o) */ topla(x,y,z):- free(y), free(z), bound(x), sayi(y), Z=X+Y. /* (i,o,o) */ topla(x,y,z):- 114

125 free(x), free(y), free(z), sayi(x), sayi(y), Z=X+Y. /* (o,o,o) */ /* 0'dan baģlayan sayıları bulma*/ sayi(0). sayi(x):- sayi(a), X = A+1. GOAL topla(ilk_sayi,7,10) Referans Değişkenler AkıĢ denetçisi bir cümleyi incelerken, bu cümlenin baģındaki bütün çıktı değiģkenlerinin cümlenin gövdesinde bağlı olup olmadığını kontrol eter. Bir cümlede bir değiģken bağlı değilse, bu değiģkenin referans değiģkeni olarak iģlem görmesi gerekir. Bu karmaģayı gösteren bir örnek aģağıda verilmiģtir. Predicates p(integer) Clauses p(x):-!. Goal p(v), V=99, write(v). Sorgudaki p yüklemi çıktı biçiminde çağrılır fakat clauses bölümündeki p yükleminde bulunan X değiģkeni bağlı değiģken değildir. AkıĢ denetimi sırasında bu fark edildiğinde, değiģkenin domains bölümündeki tip tanımına bakılır. Eğer değiģken tipi referans olarak tanımlıysa problem çıkmaz. Tanımsızsa uyarı mesajı görüntülenir. Bir cümledeki bir değiģken bağlı değilse, bu durumda cümlenin herhangi bir değer aktarması mümkün değildir. Bunun yerine referans değişkenine bir pointer yollayarak daha sonra bu noktaya gerçek değerin yazılması sağlar. Bu, bu tipteki bazı değiģkenlere değer aktarmak yerine, tip tanımının tamamına aynı iģlemin yapılmasını 115

126 gerektirir. Kayıtlara gönderilen pointerlar referans tipe ait argümanlara iletilir. Yani bileģik bir tip referans bir tip haline gelirse, bu durumda bütün alt tiplerin de referans tip olarak iģlem görmesi gerekir. BileĢik bir tipin referans tip olarak tanımlanması durumunda, derleyici diğer bütün alt tipleri de referans tip olarak kabul eder Referans Tip Tanımı AkıĢ denetçisi program içerisinde bağımsız bir değiģken bulduğunda değiģken sadece bir cümleden dönüģ sırasında bağımlı değilse uyarı verir. Bu durum sizin için uygunsa, bu tip tanımı otomatik olarak referans tip olarak kabul edilir. Bununla birlikte referans tip olarak tanımlamak istenen bir tipi domains bölümünde net olarak tanımlamak daha mantıklıdır Referens Tip ve İzleme Dizileri(array) Zorlama ve ekstra eģleģtirme gerektirdiği için, referans tipler programın çalıģma hızında genel bir azalmaya neden olur. Fakat referans tip tanımının neden olduğu problemler daha etkili biçimde kullanılabilir ve bu tip tanımlarının etkileri azaltılabilir. Referans tipler kullanıldığı zaman, Visual Prolog izleme dizini kullanır. Bu izleme dizini referans değiģkenlerin değer aldıkları anı bildirmek için kullanılırlar. Referans bir değiģkenin oluģturulması ve değer alması arasındaki herhangi bir noktaya geriye dönüģ yapıldığı zaman, bu değiģkenin yeniden değer almamıģ hale getirilmesi gerekir. Fakat bu problem düz değiģkenlerle uğraģırken meydana gelmez. Çünkü bunların oluģturulması ve değer alma noktaları aynıdır. Ġzlemede kaydedilen her bir çağrı 4 byte (32 bit bir pointerin büyüklüğü) kullanır. Gerektiğinde kuyruk büyüklüğü otomaki olarak arttırılır. Ġzin verilen maksimum büyüklük 16-bit Visual Prolog için 64K, 32-bit için ise sınırsızdır. Standart tipleri referans tip olarak kullanmak iyi bir fikir değildir. Çünkü program kullanıcının tanımladığı bu referans tipi, aynı tip için daima geçerliymiģ gibi kullanır. Bunun yerine, istenilen temel tip için referans bir tip tanımlamak daha uygundur. Örneğin aģağıdaki program parçasında kullanıcının tanımladığı tamsayi_referans_tipi tamsayılar için referans tiptir. Dolayısıyla tamsayi_referans_tipi her kullanımda 116

127 referans tip olarak iģlem görür. Fakat tamsayı tipindeki değiģken referans tip olarak değil, normal olarak integer olarak iģlem görür,. Domains tamsayi_referans_tipi= reference integer Predicates P(tamsayi_referans_tipi) Clauses P(_) Referans Tip Kullanımı Referans tip kullanımının en doğru biçimi, sadece gerekli olan birkaç yerde kullanıp geri kalan kısımların tamamında referans olmayan tipi kullanmaktır. Zaten gerekli olan durumlarda referans ve referans olmayan tipler arasında dönüģüm yapmak mümkündür. ġimdi referans olan bir tamsayıyı referans olmayan bir tamsayıya dönüģtürelim. Domains Referans_tamsayi=reference integer Predicates Donustur(referans_tamsayi, tamsayi) Clauses Donustur(X, X). Ġsmi aynı olan bir değiģken referans ve referans olmayan tipte kullanıldığı zaman dönüģüm otomatik olarak yapılır. Yukarıdaki örnekte referans_tamsayi ve tamsayi arasında dönüģüm otomatik olarak yapılır. Referans bir değiģkenin, referans olmayan bir değere dönüģtürülebilmesi için öncelikle bir değer almıģ olması gerekir. Yani referans tip olarak tanımlı bir değiģkeni dönüģtürmek için (örneğin referans tamsayılardan referans karaktere) öncelikle bu değiģkenin bir değer almıģ olduğundan emin olmak gerekir. Aksi takdirde serbest değiģken kullanılamaz Ģeklinde hata mesajı görüntülenir. Referans tip tanımlarının nasıl çalıģtığını tam olarak anlamak için aģağıdaki programı değiģik sorgularla çalıģtırılmalıdır. DOMAINS 117

128 referans_tamsayi = integer referans_liste= reference referans_tamsayi* PREDICATES nondeterm eleman(referans_tamsayi, referans_liste) ekle(referans_liste, referans_liste, referans_liste) CLAUSES eleman(x, [X _]). eleman(x, [_ L]):- eleman(x, L). ekle([], L, L). ekle([x L1], L2, [X L3]):- ekle(l1, L2, L3). GOAL eleman(1, L). AĢağıdaki sorguları da deneyin eleman(x, L), X=1. Elemanları arasında 1 olan bütün listeleri bul. eleman(1, L), eleman(2, L). Elemanları arasında 1 ve 2 olan bütün listeleri bul X=Y, eleman(x, L),eleman(Y, L), X=3. X ve Y nin eleman olduğu listeler eleman(1, L), ekle(l, [2, 3], L1). ekle(l, L, L1), eleman(1, L). 1 in iki kez eleman olduğu listeler Akış Biçimine Yeni Bir Bakış Referans bir değiģken serbest halde olmasına rağmen, bir yüklem çağrısı içinde çağrıldığı anda mevcut olabilir. Ülkeler hakkındaki programda ayni_baskentler:- ulke(baskent(kent, Kent), write(kent, \n ), fail Ģeklindeki bir sorguyla, baģkentleri ülke ismiyle aynı olan bütün ülkeleri bulmak isteyelim. Burada kent değiģkeni iki kez çıktı akıģı ile kullanılmıģtır. Fakat bu sorgu satırının söylediği Ģey; Kent değiģkeni değer aldığı anda ikinci değiģken olan Kent in de aynı değeri alması gerektiğidir. Bu yüzden her iki değiģken çağrı yapılmadan önce yaratılıp eģleģtirilir. ĠĢte bunu yapabilmek için bunların tipi referans tipe dönüģtürülür ve iki değiģken çağrı anından itibaren kullanıma girerler. 118

129 Standart tip tanımlarının referans tip haline getirmenin çok yanlıģ bir kullanım olacağı daha önce söylenmiģti. Eğer böyle bir Ģey yapılmak isteniyorsa, uygun bir referans tip tanımlamak daha mantıklıdır İkili (Binary) Ağaç Yapısının Referans Tip İle Kullanımı Önceki sıralama iģlemleri ikili ağaç yapısı ile çözülmüģtü. Aynı Ģeyi referans tip tanımı ile daha güzel biçimde yapmak mümkündür. Ağaç yapısındaki bir dalı, bir değer aldıktan sonra değiģtirmek mümkün değildir. Ağaç oluģturulurken pek çok noktanın kopyası oluģturulur. Sıralama iģlemini büyük miktarda veri üzerinde yapıldığı düģünülürse, bunun hafıza taģmasına neden olabileceği görülür. Referans bir tip, ağacın dallarını serbest değiģken olarak bırakarak, bu durumu düzeltebilir. Bir referans tipi bu Ģekilde kullanarak yeni bir dalın ilave edileceği noktanın üzerindeki dalı kopyalamaya gerek kalmaz. Örnek: Domains agac = reference t(isim, agac, agac) isim = string PREDICATES araya_ekle(isim, agac) CLAUSES araya_ekle(id, t(id,_,_)):-!. araya_ekle(id, t(id1, Agac,_)):- ID<ID1,!, araya_ekle(id, Agac). araya_ekle(id, t(_,_,agac)):- araya_ekle(id, Agac). GOAL araya_ekle("alper", Agac), araya_ekle("kasim", Agac), araya_ekle("paki", Agac). 119

130 Ġlk araya_ekle( Alper, Agac) alt hedefi ilk kural ile eģleģir ve bileģik nesne t( Alper,_,_) biçimini alır. T deki son iki argüman bağlı değiģken olmasalar da t diğer alt hedefe iletilir: araya_ekle( Kasim, Agac). Bu, agac değiģkenini t( Alper, t( Kasim,_,_),_) değerini aldırır. Son olarak son alt hedef araya_ekle( Paki, Agac) agac değiģkenini t( Alper, t( Kasim,_, t( Paki,_,_)),_) değerine atar ve sonuçta bu değer görüntülenir Referans Tip Kullanarak Sıralama Daha önce ikili ağaç kullanarak yapılan sıralama örneğini, referans ve referans olmayan tipler arasında ayrım yaparak nasıl yapabileceğini gösteren bir örnek, aģağıda verilmiģtir. DOMAINS agac=reference t(deger, agac, agac) deger=integer liste = integer* PREDICATES araya_ekle(integer, agac) agac_ekle(liste, agac) nondeterm agacin_elemanlari(integer, agac) sirala(liste, liste) CLAUSES araya_ekle(deger, t(deger,_,_)):-!. araya_ekle(deger, t(deger1,agac,_)):- Deger<Deger1,!, araya_ekle(deger, Agac). araya_ekle(deger, t(_,_,agac)):- araya_ekle(deger, Agac). agac_ekle([],_). agac_ekle([bas Kuyruk],Agac):- araya_ekle(bas,agac), agac_ekle(kuyruk, Agac). 120

131 agacin_elemanlari(_,kuyruk):- free(kuyruk),!, fail. agacin_elemanlari(x,t(_,l,_)):- agacin_elemanlari(x, L). agacin_elemanlari(x,t(refstr,_,_)):- X=RefStr. agacin_elemanlari(x,t(_,_,r)):- agacin_elemanlari(x, R). sirala(l,l1):- agac_ekle(l, Agac), findall(x, agacin_elemanlari(x,agac), L1). GOAL sirala([10,9,17,21,114,5], L), write("liste= ", L),nl. Bu örnekte referans tipler sadece agac değiģkeninde kullanılmıģtır. Diğer argümanların tamamı referans olmayan tiplerdedir Binary (İkili) Tip Visual Prolog da ikili verileri kullanmak için özel tip, ikili terimlerin elemanlarına eriģmek için özel yüklemler vardır. Ġkili terim kullanmanın tek amacı, baģka türlü anlamlı bir Ģekilde gösterilemeyen verileri kullanmak ve bunları saklamaktır. Binary terimleri okuma, bunları dosyaya aktarma iģlemi için özel yüklemler vardır. Binary terimlerin temel amacı mantıksal olmayan nesneler diğer programlama dillerinin içine kolayca yerleģtirilmesine imkan tanımaktır. Binary terimler, geriye iz sürme mekanizması çerçevesinde Prologdaki diğer terimlerden farklı davranırlar. Geriye iz sürme mekanizması, binary terimin oluģturulduğu noktadan öncesine giderse, binary terimlerin o ana kadar aldıkları değerleri kaybederler. Geriye dönüģ, herhangi bir binary terimin oluģturulduğu noktadan öncesine dönmezse, binary terimdeki değiģikliklere bir Ģey olmaz Binary Terimlerin Kullanılması Bir binary terim byte biçiminde bir dizi ve bu dizinin büyüklüğünü saklayan word (16 bit) veya dword(32 bit ortam) değiģkenden oluģur. 121

132 Diğer dillerden çağrı yapıldığında, binary tipindeki bir terim (diğer bir dildeki fonksiyonun çağrısayla aktarılan değiģken) gerçek içeriğe iģaret eder. Buradaki büyüklük alanı, alanın kendisinin sahip olduğu büyüklüktür. Binary terimler 16 bit platformlarda genelde 64K ile sınırlıdır Binary Terimlerin Yazım Biçimi Binary terimler okunup metin biçimde yazılabilir. Visual Prolog da program satırları gibi yazılabilir. Yazılım biçimi: $[b1, b2,..., bn] Burada b1, b2 vs. ilgili terimin byte olarak yazılmıģ halidir. Program akıģı içerisinde yazıldığı zaman, buradaki her byte uygun bir pozitif biçimde desimal, hegzadesimal, oktal veya karakter olarak yazılabilir. Karakter olarak yazılan byte, program çalıģırken daima hegzadesimal biçime dönüģtürülür ve 0x kısımları bulunmaz. Örnek: GOAL write("binary terimi metin biçiminde yaz: ", $['C', 12, 15, 0x14, 'e', 5], '\n') Binary Terimlerin Oluşturulması Binary terim oluģturmak için Visual Prolog da mevcut olan yüklemler sırayla aģağıda verilmiģtir makebinary(1) makebinary, tanımlanan byte sayısında bir binary terim oluģturur ve içeriğini binary 0 olarak ayarlar...., Bin=makebinary(10),

133 Burada byte sayısı, alan büyüklüğü hariç, net büyüklük olmalıdır makebinary(2) Ġki argüman alabilen biçiminde eleman büyüklüğü tanımlanabilir...., Usize=sizeof(unsigned), Bin=makebinary(10, Usize),... Bu yüklem, terim büyüklüğü eleman sayısının eleman büyüklüğüyle çarpımıyla belirtilen bir binary terim oluģturur. Örnekte eleman sayısı 10, eleman büyüklüğü ise sizeof(unsigned) olarak tanımlıdır. Terim içeriği 0 olur composebinary(2) Mevcut olan bir pointer ve bir uzunluktan bir binary terim oluģturur. Kullanım biçimi:..., Bin=composebinary(StringVar, Buyukluk), getbinarysize(1) getbinarysize, verinin önündeki alan büyüklüğünü hariç tutarak, bir binary terimin net büyüklüğünü byte türünden verir...., Buyukluk=getbinary(Bin), Binary Terimlere Erişim 4 ü giriģ, diğer 4 ü de çıkıģ elde etmek için kullanılan 8 yüklem binary terimlere eriģmek için kullanılabilir. Bunların hepsi binary terim büyüklüğü, tanımlı indeks ve istenilen maddenin büyüklüğüne (byte, word, dword veya real) bağlı olarak bu değiģkenlerin doğru aralıklarda olup olmadıklarını kontrol eder. Bu yüzden bu giriģleri, ikili terimlerin tanımlı sınırları dıģında tanımlamak ve çağırmak hataya neden olur. Ġndislerin (eleman numaraları) 0 a göre değiģir. Yani binary bir terimin ilk elemanının indisi 0, en son elemanın da N-1 olur. 123

134 getentry(2) getentry yüklemi getbyteentry, getwordentry, getdwordentry veya getrealentry biçimlerinden biri olur ve sırasıyla byte, word, dword veya real tiplerinde giriģ yapıp, giriģ alabilir. Deger= getbyteentry(bin, 3), setentry(3) getentry ye karģılık gelen bir yüklem olup byte, word, dword eya real giriģleri yapar...., setbyteentry(bin, 3, Baytlar), Binary Terimleri Eşleştirme Binary terimler de diğer terimler gibi eģleģtirilebilir. Kullanım biçimi:..., Bin1=Bin2,... EĢleĢtirme anında terimlerden biri serbest halde ise, birbirine eģitlenirler. Her ikisi de bağlı ise, bu durumda binary terimlerin birbirine eģit olup olmadıkları kontrol edilir Binary Terimleri Karşılaştırma Binary iki terim eģleģtirilirken Ģu sonuçlara dikkat edilir: Eğer büyüklükleri farklı ise, büyük olan büyük kabul edilir, değilse byte bazında karģılaģtırılırlar. Ġki farklı byte bulunduğu anda karģılaģtırma durur, sonuç toplam terimin karģılaģtırılması olarak gönderilir. Örneğin $[1, 2] $[100] den daha büyüktür fakat $[1,3] den daha küçüktür. Binary terimlerin bazı özelliklerini gösteren bir program aģağıda verilmiģtir. PREDICATES binary_karsilastir_ve_eslestir binary_karsilastir(binary, binary) al(binary) CLAUSES binary_karsilastir_ve_eslestir:- 124

135 Bin=makebinary(5), binary_karsilastir(bin, _), binary_karsilastir($[1,2], $[100]), binary_karsilastir($[0], Bin), binary_karsilastir($[1, 2, 3], $[1, 2, 4]). binary_karsilastir(b,b):-!, write(b, " = ", B, '\n'). binary_karsilastir(b1, B2):- B1>B2,!, write(b1, " > ", B2, '\n'). binary_karsilastir(b1, B2):- B1<B2,!, write(b1, " < ", B2, '\n'). al(bin):- setwordentry(bin, 3, 255), fail. al(bin):- Buyukluk=getbinarysize(Bin), X=getwordentry(Bin, 3), write("\nbuyukluk= ", Buyukluk, "X = ", X, " Binary= ", Bin, '\n'). GOAL binary_karsilastir_ve_eslestir, % Binary kaģılaģtırma ve eģleģtirme için KelimeBuyuklugu=sizeof(word), Bin=makebinary(4,KelimeBuyuklugu), al(bin), write("run-time hataları yanlıģ indeksten kaynaklanıyor:\n"), Indeks=4, trap(setwordentry(bin, Indeks, 0), E, write(bin, "teriminin kelime indeksi", Indeks, " olustururken ", E, " hatasi olustu", '\n')) Terimleri Binary Terimlere Dönüştürme BileĢik bir terimin argümanları belleğin değiģik yerlerinde olabilir. Basit tipleri doğrudan kayıtlı terimde tutulurken karmaģık olanlar (pointer ile eriģilenler ve global bir stack da olanlar) içindeki göründükleri terimin yakınlarında olmayabilir. Böyle bir terimi programdan dıģarıya yollamak zor olur. Çünkü terimin bütün içeriğinin 125

136 kopyasını almanın açık bir yolu yoktur. Dolayısıyla bir terimdeki değiģkeni baģka bir değiģkenle eģleģtirirken sadece bu terime giden pointerin bir kopyası alınmıģ olur. term_str yüklemini kullanarak, bir terimi diziye ve diziden tekrar terime dönüģtürmek mümkündür. Bu ise, sadece terimi içeriğini kopyalamak için gerektiğinde, oldukça yetersiz kalır. ĠĢte bu problemi term_bin yüklemini çözer term_bin(3) term_bin, herhangi bir tipteki terim ve binary veri bloku arasında dönüģümü, terim içeriği ve pointer sabitle bilgisini tutarak, yapar. Pointerin sabitleme bilgisi, binary veriye dönüģtürülmüģ terimi yeniden diziye dönüģtürmek için kullanılır. Kullanımı Ģöyledir: term_bin(tip, Terim, Bin) /* (i,i,o), (i,_,i) */ Tip, Terimin ait olduğu tip, Bin ise Terimin içeriğini tutan binary terimdir Hatalar ve İstisnalarla Uğraşma Kaliteli yazılımlar geliģtikçe, güvenilir programlar üretmek için hataların bulunması ve tek tek ayıklanması da önemli hale gelmektedir. Visual Prolog, program çalıģırken meydana gelen hataları kontrol etmek için standart yüklemlere sahiptir. Programın iģleyiģi esnasında meydana gelebilecek bütün hatalar DOS ortamıda PROLOG.ERR, UNIX ortamında PDCProlog.err dosyasında saklanır. Hata mesajı numarası ve yukarısı kullanıcının programında kullanması için exit kodları olarak ayrılmıģtır. Hata ve istisna durumlarıyla uğraģmak için Visual Prolog da temel olarak trap yüklemi kullanılır. Bu yüklem, run-time hatalarını ve exit yüklemiyle harekete geçirilen istisna durumları yakalayabilir. Bu yüklem kullanarak, örneğin Ctr+Break tuģlarına basılıp basılmadığını da kontrol edilebilir exit(0), exit(1) exit yüklemine yapılan bir çağrı, run-time hataya eģdeğerdir. Kullanım biçimleri: exit ve exit(cikiskodu) 126

137 Argüman kullanmadan exit yüklemini kullanmak, exit(0) gibi çalıģır. exit e giden çağrı trap yükleminde doğrudan veya dolaylı olarak çalıģtırılırsa, CikisKodu trap yüklemine geçer trap(3) Üç argüman alan bu yüklem hata yakalama ve istisna yönetimini gerçekleģtirir. Ġlk ve son argümanlar yüklem çağırma, ikinci argüman ise değiģkendir. Kullanım biçimi: trap(yuklemcagirma, CikisKodu, HataDurumundaCagrilacakYuklem) Örneğin trap(islem(p1,p2,p3), CikisKodu, hata(cikiskodu,p1)),... Ģeklindeki bir çağrı göz önüne alınırsa, iģlem yüklemi çağrılırken hata oluģursa CikisKodu ilgili hatayı verirken hata yönetme yüklemi olarak tanımladığımız hata yüklemi çağrılmıģ olur. Hata yükleminden dönüģte ise trap yüklemi baģarısız olur. Metin modu ortamında BREAK açıkken BREAK yapılırsa, yani Ctrl+Break tuģlarına basılırsa, trap yüklemi bunu yakalar ve CikisKodu değerini olarak 0 ı görüntüler. Örnek: AçılmamıĢ olan bir dosyadan dolayı hata mesajı yakalayan program aģağıda verilmiģtir. include "c:\\vip\\include\\error.con" DOMAINS file = giris_dosyasi PREDICATES hata_yakalama(integer, file) satir_al(file, string) CLAUSES hata_yakalama(err_notopen, Dosya):-!, write(dosya, " isimli dosya açık değil\n"), exit(1). hata_yakalama(hata, Dosya):-!, write(dosya, "adli dosyada",hata, " hatasi ", '\n'), exit(1). 127

138 satir_al(dosya, Satir):- readdevice(eski), readdevice(dosya), readln(satir), readdevice(eski). GOAL trap(satir_al(giris_dosyasi, Ilk), Hata, hata_yakalama(hata, giris_dosyasi)), write(ilk) errormsg(4) errormsg yüklemi, Visual Prolog hata mesajları dosyasıyla aynı biçimde olan dosyalara eriģmek için kullanılabilir. Kullanım biçimi: errormsg(dosyaadi,hatano,hatamesaji,yardimmesaji) / (i, i, o, o)/ Bu iģlem için aģağıdaki program örneği kullanılabilir: PREDICATES hata(integer) ana_kisim /*... */ CLAUSES hata(0):-!. % Ctrl+Break tuģuna basılınca bir Ģey yapma hata(h):- errormsg( prolog.err, H, HataMesaji, _), write( \nsayin Kullanici, Programınızda, H, nolu, ErrorMsg, hatasi meydana geldi ), write( \ndosyanizi, hata.txt, dosyasina yaziyorum ), save( hata.txt ). GOAL trap(ana_kisim, CikisKodu, hata(cikiskodu)) Hataların Bildirilmesi Visual Prolog daki bazı derleyici direktiflerini kullanarak, programlarınız içindeki run-time hataları kontrol edilebilir. Bu direktifler Ģu amaçlarla kullanılır: Tamsayı taģma(overflow) hatalarını kontrol edip etmeme durumu 128

139 run-time hataları hangi ayrıntı düzeyinde verileceği Yığın taģması(stack overflow) kontrolünü yapma Bu direktifler programın baģ tarafında verilebileceği gibi, VIP çalıģtırıldıktan sonra Compiler Options seçeneğiyle de verilebilir Hata Düzeyi Visual Prologun, run-time hatanın oluģtuğu yeri göstermeye yarayan çok güzel bir mekanizması vardır. Meydana gelen hatanın hangi düzeyde bildirileceğini, hatanın meydana geldiği yeri, derleyicinin errorlevel direktifi belirler. Kullanım biçimi Ģöyledir: errorlevel=n n nin alabileceği değerler 0, 1 veya 2 olabilir. Bu değerlere göre derleyicinin sunacağı hata düzeyi Ģunları kapsar: 0 Bu durumda en küçük ve en etkin hata mesajı verilir. Fakat hatanın yeri kaydedilmez, sadece hatanın numarası verilir. 1 Default olarak kabul edilen düzey budur. Hata meydana geldiğinde hatanın meydana geldiği nokta, dosyanın baģlangıcından itibaren byte türünden gösterilir. 2 Bu düzey seçildiğinde, 1 durumunda gösterilmeyen stack overflow, heap overflow, trail oveflow vs. gibi hataları görülebilir. Burada da hatanın meydana geldiği yer bildirilir. Proje bazında çalıģırken hata mesajı düzeylerini ayarlarken dikkatli olmak gerekir. Bir projede birden fazla dosya bulunacağı için, birbirine bağlı olan dosyalardaki hata düzeyleri farklı biçimde ayarlanırsa, errorlevel=0 olan bir alt dosyada hata meydana gelirse ve ana dosyada errorlevel=1 veya 2 olursa, bu durumda hatanın meydana geldiği yeri tam olarak bulmak imkansız olur lasterror(4) lasterror, en son olan hatayla ilgili bütün bilgiyi verir. Kullanım biçimi: lasterror(hatano,modul,incdosyasi,hatayeri) Burada Modul, hatanın meydana geldiği dosya adı, IncDosyasi ise include dosyasıdır. Bellek taģması hatalarının doğru olarak alabilmek için programın 129

140 errorlevel=1 olarak derlenmesi gerekir. Sadece basit hataların mesajları alınması isteniyorsa errorlevel=1 yeterlidir Terim Okuyucudan Gelen Hataları Görme consult veya readterm yüklemleri çağrıldığında okunacak satırda bir hata var ise, bu yüklemlerin hata mesajı vererek duracakları bilinmektedir. Hata nedenleri ise okunacak satırın uygun biçimde hazırlanmamıģ olmamasıdır. Örneğin: Bir diziyi sonlandırmamak Symbol türünde bir karakter yerine integer bir karakter yazmak Yüklem adı için büyük harfler kullanmak Sabit değerleri içinde yazmamak vs. readtermerror ve consulterror yüklemlerini kullanarak readterm veya consult yüklemlerinin okumaya çalıģtığı dosyalarda ne tür hatalar meydana geldiğini kontrol edebililir. consult ve readterm yüklemlerinden gelen hatalar trap yüklemi tarafından yakalanırsa, consulterror ve readtermerror yüklemlerini kullanarak hatanın nedenini görmek ve yazmak mümkündür consulterror(3) consulterror, hatalı yazımın bulunduğu satırdaki hata hakkında bilgi verir. Kullanım biçimi consulterror(satir, HataYeri, DosyadakiYeri) Satir, hatanın bulunduğu satır, HataYeri hatanın bulunduğu nokta, 3. parametre ise hatalı satırın bulunduğu yer verilir. Örnek: CONSTANTS yardim_dosyasi="prolog.hlp" hata_dosyasi="prolog.err" DOMAINS dom = a(integer) 130

141 liste= integer* DATABASE - firat_dba p1(integer, string, char, real, dom, liste) PREDICATES consult_hatalarini_ayiklama(string, integer) CLAUSES consult_hatalarini_ayiklama(dosya, Hata):- Hata>1400, Hata<1410,!, retractall(_, firat_dba), consulterror(satir, Hatanin_Yeri,_), errormsg(hata_dosayasi, Hata, Mesaj, _), str_len(bosluklar, Hatanin_Yeri), write(dosya, " dosyasinin ", Satir, " satırında ", Bosluklar, Mesaj, "meydana gelmistir"), exit(1). consult_hatalarini_ayiklama(dosya, Hata):- errormsg(hata_doyasi, Hata, Mesaj, _), write(dosya, " dosyasi açılmaya çalıģırken ", Mesaj, " hatası oluģtu"), exit(2). GOAL Dosya="test.dba", trap(consult(dosya, firat_dba), Hata, consult_hatalarini_ayiklama(dosya, Hata)), write("\n Tamam \n") readtermerror(2) readtermerror, readterm yükleminin okuduğu satırdaki hatayı verir. Kullanım biçimi: readtermerror(satir, HataYeri) Break Kontrolü (Sadece Metin Modunda) Visual Prolog daki break mekanizmasının nasıl çalıģtığına bakalım. Genelde, break için gerekli komutlar o anda çalıģan programı hemen durdurmazlar. Prolog da, istisnai 131

142 durumları yöneten bir birim vardır. Sinyal ile aktif edilen bu parça bir flag yerleģtirir. Visual Prolog bu flagı iki farklı durumda kontrol eder. Yazılan program, break-kontrolü açık halde derlenirse, her yüklem girildiğinde break-flag durumu kontrol edilir. Break-kontrol seçeneği, VIP seçeneklerinden iptal uygun direktif seçilerek (Options/Compiler Directives/Run-time check) iptal edilebilir. Library rutinlerinin bazıları break-flag kontrolü yaparlar break(1) break, bir program çalıģırken break-flag kontrolünün yapılıp yapılmayacağını belirtir. Kullanım biçimleri Ģöyledir. break(on), break(off) break(breakdurumu) DOS tabanlı pgogramlar için break komutundan kaynaklanan çıkıģ kodları daima 0 olur breakpressed(1) break-flag kurulmuģsa, break(off) olsa veya program nobreak seçeneğiyle derlense bile, breakpressed yüklemi baģarılı olur. BaĢarılı olunca, yakalanan en son sinyale göre bir çıkıģ kodu verir ve break-flagı siler DOS Metin Modunda Kritik Hata Kontrolü Bu bölüm sadece DOS metin modu ortamında geçerlidir. Dolayısıyla VPI programlarına uygulanamaz. Visual Prolog un DOS versiyonu hata durumlarıyla ilgilenen bazı rutinler içerir. Bir DOS hatası olduğu zaman DOS, criticalerror rutinini çağrır. Visual Prolog daki sistem ise, run-time editörü de bir dosya hatası bulduğunda fileerror yüklemini çağırır. Bu yüklemler global olarak tanımlanır ve kendinize ait cümlecikler kullanırsanız, library deki rutinler yerine size ait rutinleri programa bağlar. Dolayısıyla hataları daha iyi kontrol etmek mümkündür. Bu durumda.exe programlarının büyüklüğü büyük oranda azalır. criticalerror ve fileerror için global deklerasyon include dosyasında error.pre içinde hazır olarak bulunmaktadır. 132

143 criticalerror(4) Visual Prolog, bu rutini DOS kritik hatalarıyla uğraģmak için tanımlar. criticalerror yüklemi kullanılmak istenirse, ERROR.PRE dosyası programa dahil edilmelidir. Tanımlanması Ģöyledir: global predicates criticalerror(hatano, HataTuru, DiskNo, Eylem) criticalerror yüklemi daima baģarılı olmalıdır. Bu yüklem sadece.exe dosyasından çalıģır ve DOS kritik hata interrupt tutucusuyla yer değiģtirir. AĢağıdaki tabloda criticalerror yükleminin argümanlarının aldığı değerler verilmiģtir. 133

144 Tablo 8.4. Criticalerror yükleminin argümanlarının aldığı değerler Argüman Değer Anlamı HataNo = 0 = 1 = 2 = 3 = 4 = 5 = 6 = 7 = 8 = 9 = 10 = 11 Yazma korumalı diskete yazma teģebbüsü Bilinmeyen ünite Sürücü hazır değil Bilinmeyen komut Veri içinde CRC hatası YanlıĢ sürücü isteği yapı uzunluğu Arama hatası Bilinmeyen medya türü Sektör bulunamadı = 12 Yazıcıda kağıt bitmiģ Yazma hatası Okuma hatası Genel hata HataTürü = 0 = 1 = 2 Karakter araç hatası Disk okuma hatası Disk yazma hatası DiskNo = 0-25 A-Z ye kadar sürücü Eylem = 0 = 1 = 2 ÇalıĢmayı durdur ĠĢlemi yeniden dene ĠĢlemi iptal et (Tehlikeli olabilir ve tavsiye edilmez) fileerror(2) Metin modundaki bir dosya eylemi baģarısız olunca fileerror yüklemi harekete geçirilir. Kendinize ait fileerror yüklemini tanımlarsanız, bu yüklemin baģarısız olmasına izin verilmez ve bu yüklem sadece.exe uygulamalarından çalıģır. fileerror un ERROR.PRE dosyasındaki tanımlanması Ģöyledir: global predicates fileerror(integer, string) (i, i) language c as _MNU_FileError Bu tanım tipi doğrudur. Kaynak kod Prolog da olsa bile language c mutlaka belirtilmelidir Dinamik Cut Prolog daki cut statiktir. Geleneksel cut iģleminde, program akıģı ancak! sembolüne geldiği zaman cut devreye girer ve sadece içinde bulunulan cümleleri etkiler. Dolayısıyla bir cut komutunun etkisini baģka bir yükleme aktarmak mümkün değildir. Normal cut komutunun diğer bir dezavantajı da; yüklemde cut komutunu 134

145 takip eden cümlelerdeki geriye dönüģ noktalarını ortadan kaldırmadan, bir alt hedefteki diğer çözümleri arama ihtimalini ortadan kaldırmanın mümkün olmamasıdır. Visual Prolog da dinamik kesme mekanizmasında getbacktrack ve cutbacktrack yüklemleri kullanılır. Bu mekanizma sayesinde bu iki dezavantaj ortadan kalkmıģ olur. getbacktrack, geriye iz sürme noktalarının yığını içerisinde en üstteki pointer i verir. Bu noktanın üstünde kalan bütün geriye dönüģ noktaları silinebilir. Bu iki yüklemin kullanımı hakkındaki örnekler, aģağıda verilmiģtir. 1. Elimizdeki veritabanında sahislarin isim ve aylık gelirleri var. Bu sahısların arkadaģlarını kaydetmiģ durumdayız. database sahis(symbol, income) arkadas(symbol, symbol) ArkadaĢı olan veya az bir vergi ödeyen insanların listesini görmek için aģağıdaki cümlecikleri kullanabiliriz: sansli_insanlar(aradasi_var(p)):-sahis(p,_), arkadas(p,_). sansli_insanlar(zengindir(p)):-sahis(p, AylikGelir), not(zengin(aylikgelir)). Bir Ģahsın birden fazla arkadaģı varsa, ilk cümlecik birden fazla çözüm getirir. Bu arada dinamik cut kullanabiliriz. sahsli_insanlar(arkadasi_var(p)):- sahis(p,_), getbacktrack(btop), arkadas(p,_), cutbacktrack(btop). Geriye dönüģ mekanizması yapılırsa, arkadaģ yüklemi birden fazla çözüm sunabilir. Fakat cutbacktrack yüklemi çağrılarak bu ihtimal ortadan kaldırılır. Dinamik cut kullanmanın daha önemli avantajı, geriye dönüģ pointerini baģka bir yükleme geçirmek ve cut komutunu Ģartlı olarak çalıģtırmaktır. Pointer pozitif tipte olup yine pozitif tipteki değiģkenlere aktarılabilir. Örnek: Bir tuģa basıncaya kadar ekrandan girilen rakamları okuyan bir program, aģağıda sunulmuģtur. PREDICATES sayi(integer) sayilari_yaz(integer) 135

146 kullanici_komutu(unsigned) CLAUSES sayi(0). sayi(n):-sayi(n1), N=N1+1. sayilari_yaz(n):- getbacktrack(btop), sayi(n), kullanici_komutu(btop). kullanici_komutu(btop):- keypressed, cutbacktrack(btop). kullanici_komutu(_). Derleyici, cümleleri determinism bakımından kontrol eden yüklemdeki cutbacktrack yüklemini tanımaz. Yani check_term direktifini kullanırken nondeterministic cümle uyarısı alınabilir. Dinamik kesme kullanırken çok dikkatli olmak gerekir. Çünkü programın tamamını tahrip etmek, programı çalıģamaz hale getirmek mümkündür Programlama Stilleri Visual Prolog da program yazarken dikkat edilmesinde fayda olan bazı temel özellikler vardır. Bu özellikler artık kural haline gelmiģtir. Etkili programlama yapabilmek için Ģu kurallara dikkat edilmelidir: Kural 1. Fazla yüklem yerine daha fazla değişken kullanın Bu kural programın okunabilirliği ile ters orantılıdır. Genelde Prolog un dekleratif olan stili, diğer konvansiyonel yaklaģımlara göre daha az verimlidir. Örneğin, bir listenin elemanlarını tersine çeviren bir yüklem yazmak için aģağıdaki program parçası kullanılabilir: tersine_cevir(a, B):- tersine_cevir1([], A, B). tersine_cevir1(b, [], B). tersine_cevir1(a1, [U A2], B):- tersine_cevir1([u A1], A2, B). Kural 2. Çözüm olmadığı zaman program çalışmasının etkili bir biçimde bittiğinden emin olun Yazdığımız bir maksimum_deger yüklemiyle bir listedeki tamsayıların büyük bir sayıya kadar düzenli olarak arttığını, daha sonra yine düzenli bir Ģekilde azaldığını kontrol etmek istiyoruz. Bu yüklemi kullanarak maksimum_deger([1, 2, 5, 7, 11, 8, 6, 4]) Ģeklindeki bir sorgu baģarılı olur. Fakat 136

147 maksimum_deger([1, 2, 3, 9, 6, 8, 5, 4, 3]) baģarısız olur. Kural 3. Geriye İz Sürme mekanizmasını mümkün olduğunca çok kullanın. esitlik seklinde tanımlanan bir yüklemin iki listenin elemanlarını karģılaģtırmak için kullanalım. Bunun için: esitlik([], []). esitlik([u X], [U Y]):- esitlik(x, Y) kullanmak gereksizdir. Çünkü bunun yerine daha basit olan esitlik(x, X) kullanılabilir. Kural 4. Rekursiyon veya Tekrarlama Yerine Geriye İz Sürme Mekanizmasını Kullanın Geriye Ġz Sürme mekanizması bellek ihtiyacını azaltır. Bu yüzden rekursiyon yerine repeat-fail kombinasyonunu kullanmak gerekir. Bu konu hakkında birkaç örnek verelim. Alt hedefleri tekrarlı bir Ģekilde kullanmak için genelde basla gibi bir yüklem tanımlayıp sonuçları hesaplamak gerekir. Örnek: basla:- readln(x), islem_yap(x, Y), write(y), basla. Bu tür bir tanımlama gereksiz yere rekursiyon yapar. islem_yap(x,y) nondeterministic ise sistem tarafından gereksiz olan bu rekursiyon otomatik olarak ortadan kaldırılabilir. Bu durumda repeat...fail ikilisi kullanmak gerekir. Bunun için yukarıdaki iģlemleri Ģöyle yazmak mümkündür. basla:- tekrar, readln(x), islem_yap(x, Y), write(y), fail. fail komutu, islem_yap yükleminine geriye dönüģ yapar, buradan da tekrar yüklemine geçer, bu yüklem daima baģarılı olur. Burada önemli olan Ģey bu döngünün dıģına çıkmaktır. Genelde döngü dıģına çıkmak için belli Ģartlar aranıldığı için, döngü içine bu Ģartı yazmak mümkündür. Yani: basla:- tekrar, readln(x), islem_yap(x, Y), write(y), bitisi_kontrol_et(y),!. 137

148 8.15. Cut Yüklemini Yerleştirmek check_determ direktifi, cut yükleminin nereye yerleģtirilmesi gerektiği konusunda karar verirken çok faydalıdır. Non-deterministic davranıģı olan cümlecikleri deterministic hale getirip geriye dönüģü engellemek için cut kullanılmadır. Böyle bir durumda genel bir kural olarak Ģunu söyleyebiliriz: cut komutunu, programın mantığını bozmayacak Ģekilde, mümkün olduğuca bir kuralın baģına yakın bir yere konulmalıdır. Derleyici aģağıdaki iki kuralı dikate alarak bir cümleciğin deterministic veya non-deterministic olduğuna ; 2. Cümlede cut yoksa ve cümlenin baģındaki argümanlarla eģleģebilecek baģka bir cümlecik varsa 3. Cümle gövdesinde non-deterministic baģka bir yükleme çağrı varsa ve nondeterministic olan bu çağrıdan sonra cut yoksa bulunarak karar verilir. 138

149 9. ÖZEL GELİŞTİRİLMİŞ PROLOG ÖRNEKLERİ 9.1. Küçük bir Uzman Sistem örneği Bu örnekte, bazı özellikleri hakkında kullanıcıya soru sorarak 7 hayvandan biri bulunacaktır. Bu hayvanlar hakkında bilinen olgulardan hareketle geriye dönüģ mekanizması kullanılarak doğru cevap bulunmaya çalıģılacaktır. DATABASE xpositif(symbol,symbol) xnegatif(symbol,symbol) PREDICATES nondeterm aranan_canli(symbol) nondeterm canli_turu(symbol) soru_sor(symbol,symbol,symbol) sakla(symbol,symbol,symbol) positif(symbol,symbol) negatif(symbol,symbol) olgulari_sil basla CLAUSES aranan_canli(cita):- canli_turu(memelil), canli_turu(etobur), positif(sahiptir,sari_kahverengi_renklere), positif(sahiptir,siyah_benekler). aranan_canli(tiger):- canli_turu(memeli), canli_turu(etobur), positif(sahiptir, sari_kahverengi_renkler), positif(sahiptir, siyah_seritli). aranan_canli(zurafa):- 139

150 canli_turu(tirnakli), positif(sahiptir,uzun_boyunlu), positif(sahiptir,uzun_bacakli), positif(sahiptir, siyah_benekler). aranan_canli(zebra):- canli_turu(tirnakli), positif(sahiptir,siyah_seritli). aranan_canli(devekusu):- canli_turu(kus), negatif(eylem,ucar), positif(sahiptir,uzun_boyunlu), positif(sahiptir,uzun_bacakli), positif(sahiptir, siyah_beyaz_renk). aranan_canli(penguen):- canli_turu(kus), negatif(eylem,ucar), positif(eylem,yuzer), positif(sahiptir,siyah_beyaz_renk). aranan_canli(albatros):- canli_turu(kus),positif(eylem,iyi_ucar). canli_turu(memeli):- positif(sahiptir,tuylu). canli_turu(memeli):- positif(eylem,sut_verir). canli_turu(kus):- positif(sahiptir,kus_tuyleri). canli_turu(kus):- positif(eylem,ucar), positif(eylem,yumurtlar). canli_turu(etobur):- positif(eylem,et_yer). 140

151 canli_turu(etobur):- positif(sahiptir,sivri_disleri), positif(sahiptir, pencelere), positif(sahiptir,patlak_gozler). canli_turu(tirnakli):- canli_turu(memeli), positif(sahiptir,toynaklar). canli_turu(tirnakli):- canli_turu(memeli), positif(eylem,gevis_getirme). positif(x,y):- xpositif(x,y),!. positif(x,y):- not(xnegatif(x,y)), soru_sor(x,y,evet). negatif(x,y):- xnegatif(x,y),!. negatif(x,y):- not(xpositif(x,y)), soru_sor(x,y,hayir). soru_sor(x,y,evet):-!, write(x," aranan canli:",y,'\n'), readln(cevap),nl, frontchar(cevap,'e',_), sakla(x,y,evet). soru_sor(x,y,hayir):-!, write(x," aranan canli: ",Y,'\n'), readln(cevap),nl, frontchar(cevap,'h',_), sakla(x,y,hayir). sakla(x,y,evet):- 141

152 assertz(xpositif(x,y)). sakla(x,y,hayir):- assertz(xnegatif(x,y)). olgulari_sil:- write("\n\nbitirmek icin space tusuna basiniz.\n"), retractall(_,dbasedom),readchar(_). basla:- aranan_canli(x),!, write("\n Aradiginiz canli bir ",X, "olabilir."), nl,nl,olgulari_sil. basla :- write("\naradiginiz canliyi bulmak mumkun degildir.\n\n"), olgulari_sil. GOAL basla. Veritabanındaki her hayvan, sahip olduğu veya olmadığı bazı özelliklerle tanımlanmıģtır. Kullanıcının cevaplayacağı sorular olumlu(a, B) veya olumsuz(a, B) Ģeklindedir. Sorulan bir soruya evet veya hayır Ģeklinde cevap aldıktan sonra, verilen cevabın veritabanına eklenmesi gerekir. Böylece program karar verirken eski bilgileri kullanır. Burada olumlu ve olumsuz olmak üzere sadece iki yüklem kullanılmıģtır. database xpozitif(symbol, symbol) xnegatif(symbol, symbol) Böylece aradığımız hayvanın tüylü değilse, xnegative(vardir, tuy) Ģeklindeki olguyu kullandık. Pozitif ve negatif kurallar, kullanıcının verdiği cevabın önceden bilinip bilinmediğini kontrol eder. pozitif(x,y):- xpozitif(x,y),!. pozitif(x,y):- not(xnegatif(x,y)), soru_sor(x,y,evet). negatif(x,y):- 142

153 xnegatif(x,y),!. negatif(x,y):- not(xpozitif(x,y)), soru_sor(x,y,hayir). Pozitif ve negatif kurallarının ikinci kuralı, kullanıcıya yeni bir soru sormadan önce arada bir zıtlık olup olmadığını kontrol eder. Tanımladığımız soru_sor yüklemi kullanıcıya soru sorar ve alınan cevapları düzenler. Cevap e ile baģlarsa olumlu, h ile baģlarsa olumsuz olarak kabul edilir. ask(x,y,yes):-!, write(x," it ",Y,'\n'), readln(reply),nl, frontchar(reply,'y',_), remember(x,y,yes). ask(x,y,no):-!, write(x," it ",Y,'\n'), readln(reply),nl, frontchar(reply,'n',_), remember(x,y,no). remember(x,y,yes):-assertz(xpositive(x,y)). remember(x,y,no):-assertz(xnegative(x,y)). clear_facts:-write("\n\nçıkmak için boģluk tuģuna basınız\n"), retractall(_,dbasedom),readchar(_) Basit bir yön problemi Türkiye deki birkaç Ģehir arasındaki en uygun yolu bulmak için bir program yapalım. Program bize iki Ģehir arasında yol olup olmadığını sorsun. Vereceğimiz cevaba göre en uygun yolu bize göstersin. Burada geriye iz sürme ve rekursiyon metotlarını kullanacağız. Elazığ ġanlıurfa Mardin Gaziantep DOMAINS 143

154 sehir = symbol mesafe = integer PREDICATES nondeterm yol(sehir,sehir,mesafe) nondeterm guzergah(sehir,sehir,mesafe) CLAUSES yol(mardin,sanliurfa,190). yol(gaziantep,mardin,320). yol(sanliurfa,gaziantep,146). yol(sanliurfa,elazig,348). yol(gaziantep,elazig,540). guzergah(_1_sehir,_2_sehir,mesafe):- yol(_1_sehir,_2_sehi, Mesafe). guzergah(_1_sehir,_2_sehir,mesafe):- yol(_1_sehir,x,mesafe1), guzergah(x,_2_sehir,mesafe2), Mesafe=Mesafe1+Mesafe2,!. GOAL guzergah(sanliurfa,elazig, Toplam_Mesafe). Yol yüklemi için kullanılan her bir cümlede, bir Ģehirden diğerine olan yolun km cinsinden değeri verilmiģtir. guzergah yüklemi ise iki Ģehir arasında yol olduğunu göstermektedir. Güzergahı takip eden bir sürücünün mesafe parametresiyle gösterilen miktarda gideceği belirtilmiģtir. Burada güzergah yüklemi rekursiv olarak tanımlanmıģtır. Güzergah, birinci cümlede olduğu gibi sadece tek yol olabilir. Bu durumda toplam mesafe sadece iki Ģehir arasındaki yoldur. Bir Ģehirden diğerine gittikten sonra ana hedefe gidiliyorsa, bu durumda toplam yol Mesafe1+Mesafe2 olur Hazine Avcısı Labirent biçimindeki dehliz ve mağaralardan oluģan bir yerde gizli bir hazine bulunsun. Aynı yerden tekrar geçmeden, tehlikeye yakalanmadan giriģ noktasından baģlayıp emniyetli bir Ģekilde çıkıģtan geçmek ve hazineyi almak için hangi yolu takip etmeliyiz? 144

155 Önce hazinenin yerini gösteren haritaya bakalım. Giriş Bataklık denizkızı çeşme haydut gıda canavar hazine çıkıģ DOMAINS oda = symbol odalarin_listesi = oda* PREDICATES nondeterm galeri(oda,oda) nondeterm komsu_oda(oda,oda) buralara_girmek_tehlikeli(odalarin_listesi) nondeterm git(oda,oda) nondeterm guzergah(oda,oda,odalarin_listesi) nondeterm eleman(oda,odalarin_listesi) CLAUSES galeri(giris,canavar). galeri(giris,cesme). galeri(cesme,bataklik). galeri(cesme,gida). galeri(cikis,hazine). galeri(cesme,denizkizi). galeri(haydut,hazine). galeri(cesme,haydut). galeri(gida,hazine). galeri(denizkizi,cikis). galeri(canavar,hazine). 145

156 galeri(hazine,cikis). komsu_oda(x,y):-galeri(x,y). komsu_oda(x,y):-galeri(y,x). buralara_girmek_tehlikeli([canavar,haydut]). git(baslama_noktasi,bitis_noktasi):- guzergah(baslama_noktasi,bitis_noktasi,[baslama_noktasi]). git(_,_). guzergah(oda,oda,gidilen_odalar):- eleman(hazine,gidilen_odalar), write(gidilen_odalar),nl. guzergah(oda,cikis_yolu,gidilen_odalar):- komsu_oda(oda,sonraki_oda), buralara_girmek_tehlikeli(tehlikeli_odalar), not(eleman(sonraki_oda,tehlikeli_odalar)), not(eleman(sonraki_oda,gidilen_odalar)), guzergah(sonraki_oda,cikis_yolu,[sonraki_oda Gidilen_odalar]). eleman(x,[x _]). eleman(x,[_ H]):-eleman (X,H). GOAL git(cikis, giris). Buradaki her dehliz bir olguyla temsil edilmiģtir. git ve guzergah yüklemleri kuralları belirler. Sorgudan elde edeceğimiz cevapta hazineyi alıp emniyetli bir Ģekilde dıģarı çıkmak için gerekli güzergah belirtilecektir. Programdaki önemli bir özellik, rekursiv olarak tanımlı olan guzergah sayesinde gidilen odaların kataloga alınmasıdır. ÇıkıĢ odasına geldiğiniz anda üçüncü parametre o ana kadar ziyaret ettiğiniz odaları listeler. Bu odalar arasında hazine var ise, hedefe varıldı demektir. Eğer listede hazine odası yoksa, Sonraki_oda seçeneği tehlikeli odalara gidilmeyecek Ģekilde geniģletilir. 146

157 TARTIŞMA VE SONUÇ Yapay Zeka kavramı ortaya çıktıktan sonra, yurtdıģında bu konuda çok sayıda teorik çalıģma, değiģik disiplinlerde kullanılan birçok uygulama program gerçekleģtirilmiģtir. Bu programlar sayesinde, bir insan tarafından yapılması çok zaman alabilen ve hata oranı oldukça yüksek olabilen durumlar ortadan kalkmıģtır. Örneğin Digital firması yetkilileri, müģterilerinin sipariģlerine göre yeni bir sistem dizaynı yaparken, bu sistemde kullanılabilecek donanım seçeneklerinin çokluğu, her bir parçanın birden fazla parça ile uyumlu çalıģabilmesi veya bazı parçaların birbirleriyle hiç uyuģmaması gibi durumlardan dolayı, yapılan montajlarda büyük oranda hataların ortaya çıktığını; ancak yazılan bir uzman sistem ve parçalar hakkındaki gerçeklerden oluģan bir bilgi veritabanı ile bu durumun ortadan kalktığını, ayrıca yılda milyonlarca dolar tasarruf sağladıklarını belirtmiģlerdir. Bunun haricinde farklı alanlarda kullanılmak üzere hazırlanan ve baģarılı bir Ģekilde çalıģan çok sayıda uzman sistem örneği vermek mümkündür. Tıpta teģhis ve tedavi planlaması amacıyla bilgi tabancı sistemler, birçok alanda (Örneğin Laboratuar, Onkoloji veya Kardiyoloji gibi) kullanım sahası bulmaktadır. DiĢ tedavisi alanında bilgisayar kullanımı daha ziyade sadece kayıt amaçlı kullanılmaktadır. Karlsruhe deki DiĢ Hekimliği Akademisi ile Bremen Üniversitesi Yapay Zeka Laboratuarı arasında iģbirliği yapılarak, bir yazılım geliģtirilmiģtir. Bu çalıģma, diģ doktorları için bilgi tabanlı bir dökümantasyon ve karar verme sisteminin oluģturulmasını sağlamaktadır. Sistemin kullanılması halinde, diģ hekimliği ile ilgili teģhis ve tedavi önerileri yapılabilmektedir. Türkiye de ise, bu alanda çok ciddi çalıģmaların var olduğunu söylemek çok zordur. Gebze Yüksek Teknoloji Enstitüsü ndeki Yapay Zeka Bölümü nde, askeri amaçlı projeler üzerinde çalıģmalar yürütülmektedir. Ayrıca Bilkent ve Orta Doğu Teknik Üniversitelerinde yürütülmekte olan TurkLang gibi büyük projeler mevcuttur. Fakat bu çalıģmaların çoğu Unix ortamında yapılmakta olup, bireysel ve endüstriyel kullanıma yönelik değildir. Yapay Zeka ve bunun alt bölümleri olarak kabul edilen Uzman Sistemler, Yapay Sinir Ağları, Tabii Dil ĠĢlenmesi gibi alanlarda program yapmak için mantık dillerinin 147

158 yanı sıra, Pascal, C++ gibi konvansiyonel programlama dilleri de kullanılmaktadır. Prolog (Programming in Logic) mantık dillerinden en popüler olanıdır. Önceleri daha çok Unix, VAX gibi iģletim sistemleriyle çalıģan anaçatı bilgisayarlarda kullanılan Prolog, zamanla DOS, daha sonraları ise Windows ve diğer iģletim sistemlerine de aktarılmıģtır. Visual Prolog, iģte bu aģamalardan sonra çıkarılan, çoklu ortamlarda rahatlıkla kullanılabilen bir mantık dilidir. Visual Prolog un diğer konvansiyonel dillerden ayrıldığı bazı özellikler Ģunlardır: a) Visual Prolog prosedürel değil tamamen dekleratif bir yapıya sahiptir. Yani çözümü aranan bir problemin nasıl çözüleceğini tanımlamak yerine, problemin kendisini tanımlamak yeterlidir. Kullanıcı tarafından verilen gerçeklere dayanarak, Prolog da var olan Inference Engine(Karar verme motoru) istenilen problem için mümkün olan bütün çözümleri bulur. b) Visual Prolog daki Geriye İz Sürme mekanizması, konvansiyonel dillerin hiçbirinde bulunmayan güçlü bir özelliktir. Bu özellik sayesinde konvansiyonel dillerdeki FOR..NEXT, DO..WHILE gibi döngüler ortadan kalkar. Prolog, bu özelliği sayesinde, çözüm aranan bir sorguya uygun bütün çözümleri kendiliğinden bulur. Bu durum, döngü komutlarının neden olabileceği hataları baģtan itibaren ortadan kaldırır. c) Visual Prolog un diğer bir özelliği ise, nesneler arasındaki iliģkilerin çok kolay bir Ģekilde tanımlanabilmesi, bu iliģkilere dayalı iģlemler yapabilmesidir. Örneğin, kullanilir( Visual Prolog, uzman_sistemler) Ģeklinde ifade edilebilen Visual Prolog dili uzman sistemlerde kullanılır cümlesini, konvansiyonel dillerle ifade etmek mümkün değildir. Visual Prolog ile uygulama Programları yazarken, nesneler arasındaki iliģkileri ifade etmek son derece kolay olmasına rağmen, uygulamanın sonuçları hakkında Türkçe bilgi vermek ve Türkçe de düzgün cümleler kurmak açısından bazı zorluklar mevcuttur. Bunun temel nedeni, Ġngilizce ve Türkçe cümle yapılarında öğelerin diziliģlerinde farklılıklar bulunmasıdır. Bu yüzden, Türkçe ifade edilen bir cümlede, özne ve yüklem arasında akıcı bir iliģki kurabilmek için, öğeler arasındaki özelliklerin önceden veritabanına yüklenmesi faydalı olacaktır. Bu çalıģma sayesinde, Prolog un Türkçe ye uyarlanmasında karģılaģılan problemler detaylı olarak ele alınmıģ, 148

159 problemlerin en doğru Ģekilde nasıl çözümlenebileceği konusunda bazı yazılımlar geliģtirilmiģtir. Visual Prolog kullanarak yapay zeka konusunda çalıģma yapacaklar için önemli birçok ipuçları örneklerle verildiği bu tez çalıģması sayesinde, yapay zeka alanında Türkçe uygulamalarda önemli geliģmeler sağlanabilecektir. 149

160 KAYNAKLAR (1) STERLING; Leon; SHAPHIRO, Ehud; The Art of Prolog, Advanced Programming Techniques, The MIT Press, London, England, (2) CLOCKSIN, W.F, MELLISH, C.S, Programming in Prolog, Springer-Verlag Berlin Heidelberg, Germany, (3) O KEEFE, Richard A.; The Craft of Prolog, The MIT Press, London, England, 1990 (4) CASTILLO, E., ALVAREZ, E., Expert Systems: Uncertainity and Learning, Computational Mechanics Publications, Southampton, Boston, America, 1991 (5) GIARRATANO, JOSEPH. C, Expert Systems: Principles and Programming, PWS-KENT Publishing Company, Boston, America,1989. (6) IGNIZIO, JAMES. P., Introduction to Expert Systems, McGraw-Hill, Inc., America, (7) PDC, Visual Prolog Language Tutorial, Copenhagen, Denmark, (8) KUġ, M.; VAROL, A.; OĞUROL, Y.; VAROL, Y.: Verarbeitung von unsiherem Wissen mit Fuzzy-Prolog, Second Turkish-German Joint Computer Application Days, October, Konya, 1998 (9) OĞUROL, Y.; VAROL, A.; KUġ, M.: Anforderungen und Lösungsansätze einer transferierbaren Entwicklungsumgebung für die medizinische Wissenverarbeitung, Second Turkish-German Joint Computer Application Days, October, Konya, (10) VAROL, A.; VAROL, N.: ESTA Ġle Bilgisayar Destekli Eğitim, Beta Basım Yayım Dağıtım A.ġ., 299, (11) VAROL, A.; VAROL, N.: ESTA Bilgisayar Yazılımı Ġle Uzman Sistemlerin Hazırlanması Teknikleri, Süleyman Demirel Üniversitesi, Makine Mühendisliği Dergisi, Cilt 1, Sayı 9, 67-72,

161 (12) KUġ, M.; VAROL, A.; OĞUROL, Y.: Uzman Sistemin DiĢçilik Alanında Kullanımına Ait Bir Uygulama, Endüstri&Otomasyon, Aylık Elektrik, Elektronik, Makine, Bilgisayar ve Kontrol Sistemleri Dergisi, Sayı: 18, 1998 (13) KUġ, M.; VAROL, A.; OĞUROL, Y.: Uzman Sistemin DiĢçilik Alanında Kullanımına Ait Bir Uygulama, Endüstri&Otomasyon, Aylık Elektrik, Elektronik, Makine, Bilgisayar ve Kontrol Sistemleri Dergisi, Sayı: 18, 1998 (14) VAROL, A.; VAROL, N.: Uzman Sistemlerde ESTA Yazılımının Önemi, BiliĢim'96, Eylül 1996 Ġstanbul, Bildiriler Kitabı, , (15) VAROL, A.; VAROL, N.: Uzman Sistem Hazırlanırken Hangi Kriterler Göz Önünde Bulundurulmalı, GAP 2. Mühendislik Kongresi, Mayıs 1998, ġanlıurfa, Bildiri Kitabı, S: ,

162 ŞEKİLLER ve TABLOLAR ġekil 1. Aile Fertlerinin ġecere Olarak Gösterilmesi ġekil 2. ġekil 6.1 deki ağaç yapısında Aşağıya-Doğru-Arama metodunun uygulanması ġekil 3. Binary tarama yapısı Tablo 3.1: Visual Prolog da Tipler ve Alabilecekleri değerler Tablo 7.2. Listelerin baģ ve kuyruk halinde gösterilmeleri Tablo 7.3: Liste eģleģtirme örnekleri Tablo 8.4. Criticalerror yükleminin argümanlarının aldığı değerler

Uygulamalı Yapay Zeka. Dr. Uğur YÜZGEÇ Ders 2: Prolog Giriş

Uygulamalı Yapay Zeka. Dr. Uğur YÜZGEÇ Ders 2: Prolog Giriş Uygulamalı Yapay Zeka Dr. Uğur YÜZGEÇ Ders 2: Prolog Giriş Prolog Yazılımı Bedava Prolog yorumlayıcıları var Linux, Windows, Mac OS Çok fazla sayıda Prolog yazılımı indirmek mümkün Bunlardan birkaçı SWI

Detaylı

Program AkıĢ Kontrol Yapıları

Program AkıĢ Kontrol Yapıları C PROGRAMLAMA Program AkıĢ Kontrol Yapıları Normal Ģartlarda C dilinde bir programın çalıģması, komutların yukarıdan aģağıya doğru ve sırasıyla iģletilmesiyle gerçekleģtirilir. Ancak bazen problemin çözümü,

Detaylı

Mühendislik Fakültesi Elektrik-Elektronik Mühendisliği C Programlama 3. Bölüm Veri Tipleri ve Değişkenler

Mühendislik Fakültesi Elektrik-Elektronik Mühendisliği C Programlama 3. Bölüm Veri Tipleri ve Değişkenler Mühendislik Fakültesi Elektrik-Elektronik Mühendisliği C Programlama 3. Bölüm Veri Tipleri ve Değişkenler C Programlama Dr. Serkan DİŞLİTAŞ 3.1. Sabitler Sabitler, tanımlanmasıyla birlikte program içerisinde

Detaylı

Fortran komut satırı toplam 80 kolon ve 5 bölgeden oluģur. Komut satırının yapısı aģağıdaki gibidir:

Fortran komut satırı toplam 80 kolon ve 5 bölgeden oluģur. Komut satırının yapısı aģağıdaki gibidir: FORTRAN (FORmula TRANslation) Fortran komut satırı toplam 80 kolon ve 5 bölgeden oluģur. Komut satırının yapısı aģağıdaki gibidir: 1 2...5 6 7...72 73...80 A B C D E A Bölgesi: (1. kolon) B Bölgesi: (2-5

Detaylı

Dekleratif Programlama. Örnek : Aile Ağacı. SWI-Prolog. Prolog Dekleratif programlama dili

Dekleratif Programlama. Örnek : Aile Ağacı. SWI-Prolog. Prolog Dekleratif programlama dili Prolog Programlarının özellikleri: PROgrammig in LOGic Semboller üzerinde çalışma Problemlerin çözümünü tanımlama yerine çıkarım yapma Doğal ğ dille düşünülen ş şeylerin y kodlanması kolay Gerçekler ve

Detaylı

Program akıģı sırasında belirtilen satır numaralı yere gitmek için kullanılır. Genel formu: [<satır numarası>] GOTO <satır numarası 1> GOTO n

Program akıģı sırasında belirtilen satır numaralı yere gitmek için kullanılır. Genel formu: [<satır numarası>] GOTO <satır numarası 1> GOTO n KONTROL DEYİMLERİ Kontrol deyimleri bir programın normal akıģını değiģtirmek için kullanılır. Aksi söylenmedikçe programın komut satırları birbiri ardına çalıģtırılır. Program içindeki yapılan sorgulamalara

Detaylı

PROGRAMLAMAYA GİRİŞ DERS 2

PROGRAMLAMAYA GİRİŞ DERS 2 PROGRAMLAMAYA GİRİŞ DERS 2 Program editörde oluşturulur ve diske kaydedilir Tipik Bir C Programı Geliştirme Ortamının Temelleri 1. Edit 2. Preprocess 3. Compile 4. Link 5. Load 6. Execute Önişlemci programı

Detaylı

PASCAL PROGRAMLAMA DİLİ YAPISI

PASCAL PROGRAMLAMA DİLİ YAPISI BÖLÜM 3 PASCAL PROGRAMLAMA DİLİ YAPISI 3.1. Giriş Bir Pascal programı en genel anlamda üç ayrı kısımdan oluşmuştur. Bu kısımlar bulunmaları gereken sıraya göre aşağıda verilmiştir. Program Başlığı; Tanımlama

Detaylı

Değişkenler. Geçerli değişken isimleri : baslamazamani, ad_soyad, x5 Geçersiz değişken isimleri : 3x, while

Değişkenler. Geçerli değişken isimleri : baslamazamani, ad_soyad, x5 Geçersiz değişken isimleri : 3x, while Değişkenler Değişkenler bir bilginin bellekteki konumunu temsil eden sembolik isimlerdir. Bilgisayarda hemen hemen tüm işlemler bellekte yapılır. Program çalıştırıldığında değişken ve bu değişkenin türüne

Detaylı

Javascript. 1) Notepad++ aşağıdaki kodları yazıp deneme.html olarak kaydedelim. 2) Biraz önceki sayfa sadece html kodların içeriyordu.

Javascript. 1) Notepad++ aşağıdaki kodları yazıp deneme.html olarak kaydedelim. 2) Biraz önceki sayfa sadece html kodların içeriyordu. Javascript Html sayfalarının içine yazılarak, sayfayı daha etkileşimli hale getirir. click olayları, uyarı mesajları gibi hareketlerle sayfayı daha dinamik hale getirir. Javascript olmadan yazılan html

Detaylı

C Programlama Dilininin Basit Yapıları

C Programlama Dilininin Basit Yapıları Bölüm 2 C Programlama Dilininin Basit Yapıları İçindekiler 2.1 Sabitler ve Değişkenler......................... 13 2.2 Açıklamalar (Expresions)........................ 14 2.3 İfadeler (Statements) ve İfade

Detaylı

C# Programlama Dili. İlk programımız Tür dönüşümü Yorum ekleme Operatörler

C# Programlama Dili. İlk programımız Tür dönüşümü Yorum ekleme Operatörler C# Programlama Dili İlk programımız Tür dönüşümü Yorum ekleme Operatörler 1 İlk Programımız Bu program konsol ekranına Merhaba dünya! yazıp kapanır. Programı geçen derste anlatıldığı gibi derleyin, sonra

Detaylı

VERİ TABANI I. Yrd.Doç.Dr. İlker ÜNAL. Teknik Bilimler Meslek Yüksekokulu

VERİ TABANI I. Yrd.Doç.Dr. İlker ÜNAL. Teknik Bilimler Meslek Yüksekokulu VERİ TABANI I Yrd.Doç.Dr. İlker ÜNAL Teknik Bilimler Meslek Yüksekokulu Veri Tabanı Bileşenleri Tablolar : Veritabanının temel nesnesi tablolardır. Bilgilerin asıl tutulduğu yer tablodur. Diğer veritabanı

Detaylı

1. VERİ TABANI KAVRAMLARI VE VERİ TABANI OLUŞTUMA

1. VERİ TABANI KAVRAMLARI VE VERİ TABANI OLUŞTUMA BÖLÜM15 D- VERİ TABANI PROGRAMI 1. VERİ TABANI KAVRAMLARI VE VERİ TABANI OLUŞTUMA 1.1. Veri Tabanı Kavramları Veritabanı (DataBase) : En genel tanımıyla, kullanım amacına uygun olarak düzenlenmiş veriler

Detaylı

Diziler İndisli Değişkenler

Diziler İndisli Değişkenler Diziler İndisli Değişkenler Aynı tür bilgileri (öğrenci isimleri, şehir isimleri, kapı numaraları, fakülteler vbg.) bellekte tutmak için kullanabileceğimiz listelere dizi adı verilir. Dizi kullanmanın

Detaylı

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Uzaktan Eğitim Uygulama ve Araştırma Merkezi JAVA PROGRAMLAMA Öğr. Gör. Utku SOBUTAY İÇERİK 2 Java da Fonksiyon Tanımlamak Java da Döngüler Java da Şart İfadeleri Uygulamalar Java da Fonksiyon Tanımlamak JAVA DA FONKSİYON TANIMLAMAK 4 Fonksiyonlar;

Detaylı

TEMEL BİLGİSAYAR BİLİMLERİ

TEMEL BİLGİSAYAR BİLİMLERİ TEMEL BİLGİSAYAR BİLİMLERİ Doç. Dr. M.Ümit GÜMÜŞAY YTÜ - 2012 2 PROGRAMLAMA MANTIĞI Herhangi bir amaç için hazırlanan programın mantık hataları içermesi durumunda, alınacak sonucunda yanlış olacağı aşikardır.

Detaylı

ENF182 Temel Bilgisayar Bilimleri Ö Ğ R. G Ö R. G Ö K H A N K U T L U A N A

ENF182 Temel Bilgisayar Bilimleri Ö Ğ R. G Ö R. G Ö K H A N K U T L U A N A ENF182 Temel Bilgisayar Bilimleri Ö Ğ R. G Ö R. G Ö K H A N K U T L U A N A F O N K S Ġ Y O N L A R Temel Fonksiyonlar Matematiksel Fonksiyonlar Ġstatiksel Fonksiyonlar Metinsel Fonksiyonlar Tarih Fonksiyonları

Detaylı

Sınav tarihi : Süre : 60 dak. a) ABCDE b) BCDE c) ABCD d) kod hatalı e) BCD

Sınav tarihi : Süre : 60 dak. a) ABCDE b) BCDE c) ABCD d) kod hatalı e) BCD Selçuk Üniversitesi, Mühendislik Fakültesi, Harita Mühendisliği Bölümü Yıliçi Sınavı Test Soruları Adı soyadı : Öğrenci no : Sınav tarihi : 13.04.2015 Süre : 60 dak. 1. Hangisi gerçek sayı değişmezi değildir?

Detaylı

Akış Kontrol Mekanizmaları

Akış Kontrol Mekanizmaları Akış Kontrol Mekanizmaları 1 Akış Kontrol Mekanizmaları if else switch for döngüsü for döngüsünün çalışma prensibi for döngüsüyle ilgili örnekler for döngüsüyle ilgili kurallar while döngüsü while döngüsünün

Detaylı

Lambda İfadeleri (Lambda Expressions)

Lambda İfadeleri (Lambda Expressions) Lambda İfadeleri (Lambda Expressions) Lambda İfadeleri, değişkenlere değer atamak için kullanılan sadeleştirilmiş anonim (isimsiz) fonksiyonlardır. Bu fonksiyonlar matematikteki ve bilgisayar bilimlerindeki

Detaylı

Programlama Dilleri. C Dili. Programlama Dilleri-ders02/ 1

Programlama Dilleri. C Dili. Programlama Dilleri-ders02/ 1 Programlama Dilleri C Dili Programlama Dilleri-ders02/ 1 Değişkenler, Sabitler ve Operatörler Değişkenler (variables) bellekte bilginin saklandığı gözlere verilen simgesel isimlerdir. Sabitler (constants)

Detaylı

Bulanık Mantığa Giriş

Bulanık Mantığa Giriş Bulanık Mantığa Giriş J E O L O J Ġ M Ü H E N D Ġ S L Ġ Ğ Ġ A. B. D. E S N E K H E S A P L A M A Y Ö N T E M L E R Ġ - I D E R S Ġ DOÇ. DR. ERSAN KABALCI BULANIK MANTIK Klasik mantık sistemleri, sadece

Detaylı

HSancak Nesne Tabanlı Programlama I Ders Notları

HSancak Nesne Tabanlı Programlama I Ders Notları SABİTLER VE DEĞİŞKENLER Değişken, verilerin bellekte geçici olarak kaydedilmesini ve gerektiğinde kullanılmasını sağlayan değerdir. Nesne tabanlı programlama dilinde değişken kullanımı diğer programlama

Detaylı

Algoritma ve Akış Diyagramları

Algoritma ve Akış Diyagramları Algoritma ve Akış Diyagramları Bir problemin çözümüne ulaşabilmek için izlenecek ardışık mantık ve işlem dizisine ALGORİTMA, algoritmanın çizimsel gösterimine ise AKIŞ DİYAGRAMI adı verilir 1 Akış diyagramları

Detaylı

PROGRAMLAMAYA GİRİŞ. Öğr. Gör. Ayhan KOÇ. Kaynak: Algoritma Geliştirme ve Programlamaya Giriş, Dr. Fahri VATANSEVER, Seçkin Yay.

PROGRAMLAMAYA GİRİŞ. Öğr. Gör. Ayhan KOÇ. Kaynak: Algoritma Geliştirme ve Programlamaya Giriş, Dr. Fahri VATANSEVER, Seçkin Yay. PROGRAMLAMAYA GİRİŞ Öğr. Gör. Ayhan KOÇ Kaynak: Algoritma Geliştirme ve Programlamaya Giriş, Dr. Fahri VATANSEVER, Seçkin Yay., 2007 Algoritma ve Programlamaya Giriş, Ebubekir YAŞAR, Murathan Yay., 2011

Detaylı

MTM 305 MĠKROĠġLEMCĠLER

MTM 305 MĠKROĠġLEMCĠLER KARABÜK ÜNĠVERSĠTESĠ TEKNOLOJĠ FAKÜLTESĠ MEKATRONĠK MÜHENDĠSLĠĞĠ BÖLÜMÜ MTM 305 MĠKROĠġLEMCĠLER ArĢ. Gör. Emel SOYLU ArĢ. Gör. Kadriye ÖZ Assembly Dili Assembly programlama dili, kullanılan bilgisayar

Detaylı

ELN1001 BİLGİSAYAR PROGRAMLAMA I

ELN1001 BİLGİSAYAR PROGRAMLAMA I ELN1001 BİLGİSAYAR PROGRAMLAMA I DEPOLAMA SINIFLARI DEĞİŞKEN MENZİLLERİ YİNELEMELİ FONKSİYONLAR Depolama Sınıfları Tanıtıcılar için şu ana kadar görülmüş olan özellikler: Ad Tip Boyut Değer Bunlara ilave

Detaylı

4- Turbo Pascal Bilgisayar Programlamada Kullanılan Şart Yapıları

4- Turbo Pascal Bilgisayar Programlamada Kullanılan Şart Yapıları 4- Turbo Pascal Bilgisayar Programlamada Kullanılan Şart Yapıları Şart yapıları bir bilgisayar programının olmazsa olmazlarındandır. Şart yapıları günlük hayatımızda da çok fazla karşılaştığımız belirli

Detaylı

BÖLÜM 6: KARŞILAŞTIRMALI KONTROL YAPILARI

BÖLÜM 6: KARŞILAŞTIRMALI KONTROL YAPILARI BÖLÜM 6: KARŞILAŞTIRMALI KONTROL YAPILARI C programlama dilinde, diğer programlama dillerinde olduğu gibi, işlemler, ilk satırdan başlamak üzere sırayla çalışır. Program kontrol yapıları ise, programın

Detaylı

Seri No Takibi İÇERİK

Seri No Takibi İÇERİK Doküman Kodu : TNS008 İlk Yayın Tarihi : Mart 2018 Revizyon Tarihi : Mart 2018 Revizyon No : 1 İÇERİK GENEL BĠLGĠ SERĠ NO TAKĠBĠ Seri No Seri No Parametre Seçimi ile Stok menü Stok kart Alım genel parametreleri

Detaylı

Ders Tanıtım Sunumu. Internet Programming II. Elbistan Meslek Yüksek Okulu Bahar Yarıyılı. Öğr. Gör. Murat KEÇECİOĞLU 1

Ders Tanıtım Sunumu. Internet Programming II. Elbistan Meslek Yüksek Okulu Bahar Yarıyılı. Öğr. Gör. Murat KEÇECİOĞLU 1 Ders Tanıtım Sunumu Internet Programming II Elbistan Meslek Yüksek Okulu 2012 2013 Bahar Yarıyılı Öğr. Gör. Murat KEÇECİOĞLU 1 PHP Program Yapısı Php çoğunlukla HTML etiketleri arasına gömülerek kullanılır.

Detaylı

2013-14 GÜZ YY. - MKT103 - GÖRSEL PROGRAMLAMA DERSİ - ARA SINAVI

2013-14 GÜZ YY. - MKT103 - GÖRSEL PROGRAMLAMA DERSİ - ARA SINAVI 2013-14 GÜZ YY. - MKT103 - GÖRSEL PROGRAMLAMA DERSİ - ARA SINAVI KOÜ Mekatronik Mühendisliği Bölümü/MKT-103-Görsel Programlama Dersi - Ara Sınav J-grubu Ad-Soyad:...No:... J GRUBU-süre:70dk 1.) Aşağıdaki

Detaylı

KÜMELER 05/12/2011 0

KÜMELER 05/12/2011 0 KÜMELER 05/12/2011 0 KÜME NEDİR?... 2 KÜMELERİN ÖZELLİKLERİ... 2 KÜMELERİN GÖSTERİLİŞİ... 2 EŞİT KÜME, DENK KÜME... 3 EŞİT OLMAYAN (FARKLI) KÜMELER... 3 BOŞ KÜME... 3 ALT KÜME - ÖZALT KÜME... 4 KÜMELERDE

Detaylı

HSancak Nesne Tabanlı Programlama I Ders Notları

HSancak Nesne Tabanlı Programlama I Ders Notları DİZİLER Bellekte ard arda yer alan aynı türden nesneler kümesine dizi (array) denilir. Bir dizi içerisindeki bütün elemanlara aynı isimle ulaşılır. Yani dizideki bütün elemanların isimleri ortaktır. Elemanlar

Detaylı

C# Yazım Kuralları ERCİYES. Ü. BİLGİSAYAR M. COMPUTER PROGRAMMING II 1 FEHİM KÖYLÜ

C# Yazım Kuralları ERCİYES. Ü. BİLGİSAYAR M. COMPUTER PROGRAMMING II 1 FEHİM KÖYLÜ C# Yazım Kuralları 1 İçindekiler C# Yazım Kuralları Veritipleri Değişkenler Operatörler Sınıflar Nesneler, Özellik, Metot ve Olay Bileşenler 2 C# yazım kuralları Deyimlerde büyük küçük harf yazıma uyulmalı

Detaylı

enum bolumler{elektronik, insaat, bilgisayar, makine, gida};

enum bolumler{elektronik, insaat, bilgisayar, makine, gida}; BÖLÜM 12: Giriş C programlama dilinde programcı kendi veri tipini tanımlayabilir. enum Deyimi (Enumeration Constants) Bu tip, değişkenin alabileceği değerlerin belli (sabit) olduğu durumlarda programı

Detaylı

VERİ TABANI YÖNETİM SİSTEMLERİ I

VERİ TABANI YÖNETİM SİSTEMLERİ I BÖLÜM 11 11. SQL de JOIN (BİRLEŞTİRME) İŞLEMİ 11.1. JOIN (Birleştirme) İşlemi Veri tabanı kayıtları oluşturulurken bütün bilgiler bir tabloda değil de, birkaç tablo üzerinde tutulur. Bu dataların daha

Detaylı

Göstericiler (Pointers)

Göstericiler (Pointers) C PROGRAMLAMA Göstericiler (Pointers) C programlama dilinin en güçlü özelliklerinden biridir. Göstericiler, işaretçiler yada pointer adı da verilmektedir. Gösterici (pointer); içerisinde bellek adresi

Detaylı

Nesne Yönelimli Programlama

Nesne Yönelimli Programlama 1 Nesne Yönelimli Programlama Hazırlayan: M.Ali Akcayol Gazi Üniversitesi Bilgisayar Mühendisliği Bölümü Genel Bilgiler Ders konuları 1. Programlamaya Giriş 2. Program Denetimi ve Operatörler 3. Nesnelerin

Detaylı

Fonksiyonlar. C++ ve NESNEYE DAYALI PROGRAMLAMA 51. /* Fonksiyon: kup Bir tamsayının küpünü hesaplar */ long int kup(int x) {

Fonksiyonlar. C++ ve NESNEYE DAYALI PROGRAMLAMA 51. /* Fonksiyon: kup Bir tamsayının küpünü hesaplar */ long int kup(int x) { Fonksiyonlar Kendi içinde bağımsız olarak çalışabilen ve belli bir işlevi yerine getiren program modülleridir. C programları bu modüllerden (fonksiyonlar) oluşurlar. Fonksiyonların yazılmasındaki temel

Detaylı

Bu dersimizde pic pinlerinin nasıl input yani giriş olarak ayarlandığını ve bu işlemin nerelerde kullanıldığını öğreneceğiz.

Bu dersimizde pic pinlerinin nasıl input yani giriş olarak ayarlandığını ve bu işlemin nerelerde kullanıldığını öğreneceğiz. Ders-2: ---------- Bu dersimizde pic pinlerinin nasıl input yani giriş olarak ayarlandığını ve bu işlemin nerelerde kullanıldığını öğreneceğiz. Hazırlanan programlarda pic in zaman zaman dış ortamdan bilgi

Detaylı

Sınav tarihi : Süre : 60 dak. a) strstr b) strchr c) strcat d) strcpy e) strlen. a) b) d) e) 0

Sınav tarihi : Süre : 60 dak. a) strstr b) strchr c) strcat d) strcpy e) strlen. a) b) d) e) 0 Selçuk Üniversitesi, Mühendislik Fakültesi, Harita Mühendisliği Bölümü Bitirme Sınavı Test Soruları Adı soyadı : Öğrenci no : Sınav tarihi : 01.06.2017 Süre : 60 dak. 1. t değişkeni hakkında aşağıdakilerden

Detaylı

Veritabanı. SQL (Structured Query Language)

Veritabanı. SQL (Structured Query Language) Veritabanı SQL (Structured Query Language) SQL (Structured Query Language) SQL, ilişkisel veritabanlarındaki bilgileri sorgulamak için kullanılan dildir. SQL, bütün kullanıcıların ve uygulamaların veritabanına

Detaylı

Üst düzey dillerden biri ile yazılmış olan bir programı, makine diline çeviren programa derleyici denir. C++ da böyle bir derleyicidir.

Üst düzey dillerden biri ile yazılmış olan bir programı, makine diline çeviren programa derleyici denir. C++ da böyle bir derleyicidir. İST 205 Bilgisayar Programlama III C Programlamaya Giriş ve Matematiksel-İstatistiksel Uygulamalar Y.Doç.Dr. Levent Özbek Ankara Üniversitesi Fen Fakültesi İstatistik Bölümü Tel: 0.312.2126720/1420 [email protected]

Detaylı

k ise bir gerçek sayı olsun. Buna göre aşağıdaki işlemler Matlab da yapılabilir.

k ise bir gerçek sayı olsun. Buna göre aşağıdaki işlemler Matlab da yapılabilir. MATRİS TRANSPOZU: Bir matrisin satırlarını sütun, sütunlarınıda satır yaparak elde edilen matrise transpoz matris denilir. Diğer bir değişle, eğer A matrisi aşağıdaki gibi tanımlandıysa bu matrisin transpoz

Detaylı

Genel Programlama II

Genel Programlama II Genel Programlama II 22.03.2011 1 Yapılar ( Structures ) Yapılar ( structures ); tam sayı, karakter vb. veri tiplerini gruplayıp, tek bir çatı altında toplar. Bu gruplandırma içinde aynı ya da farklı veri

Detaylı

C#(Sharp) Programlama Dili

C#(Sharp) Programlama Dili Değişkenler C#(Sharp) Programlama Dili Program yazarken her zaman sabit verilerle çalışmayız, çoğu zaman programımızda bir verinin kullanıcının davranışına göre değişmesi gerekir. Kullanıcıdan bir metin

Detaylı

1 PROGRAMLAMAYA GİRİŞ

1 PROGRAMLAMAYA GİRİŞ İÇİNDEKİLER IX İÇİNDEKİLER 1 PROGRAMLAMAYA GİRİŞ 1 Problem Çözme 1 Algoritma 1 Algoritmada Olması Gereken Özellikler 2 Programlama Dilleri 6 Programlama Dillerinin Tarihçesi 6 Fortran (Formula Translator)

Detaylı

C++ Giriş Ders 1 MSGSU Fizik Bölümü Ferhat ÖZOK Kullanılacak kaynak: Published by Juan Soulié

C++ Giriş Ders 1 MSGSU Fizik Bölümü Ferhat ÖZOK Kullanılacak kaynak:  Published by Juan Soulié Kullanılacak kaynak: http://www.cplusplus.com/doc/tutorial/ Published by Juan Soulié C++ Nedir? Arttırılmış C demektir ve C dilinin geliştirilmiş halini yansıtır. C++ öğrenmeden önce herhangi bir programlama

Detaylı

Sorguların Çalışması. Kurallar. ?-anne(ayse,ahmet). ?-anne(ayse,ahmet). Geriye Doğru İz Sürme

Sorguların Çalışması. Kurallar. ?-anne(ayse,ahmet). ?-anne(ayse,ahmet). Geriye Doğru İz Sürme Örnek : Aile Ağacı Kural oluşturmak Ahmet in annesi yada babası kimdir? Bilgi tabanımızda anne yada baba diye bir ilişki ş tanımlı değil. Bunlar tek tek tanımlanabilir. Fakat bu pek anlamlı olmaz. anne(ayse,fatma).

Detaylı

Internet Programming II

Internet Programming II Internet Programming II Elbistan Meslek Yüksek Okulu 2016 2017 Bahar Yarıyılı Öğr. Gör. Murat KEÇECĠOĞLU 1 PHP Program Yapısı Php çoğunlukla HTML etiketleri arasına gömülerek kullanılır. Form işlemleri

Detaylı

6. HAFTA KBT204 İNTERNET PROGRAMCILIĞI II. Öğr.Gör. Hakan YILMAZ. [email protected]

6. HAFTA KBT204 İNTERNET PROGRAMCILIĞI II. Öğr.Gör. Hakan YILMAZ. hakanyilmaz@karabuk.edu.tr 6. HAFTA KBT204 İNTERNET PROGRAMCILIĞI II Öğr.Gör. Hakan YILMAZ [email protected] Karabük Üniversitesi Uzaktan Eğitim Uygulama ve Araştırma Merkezi 2 İçindekiler For Each... Next... 3 Döngüyü

Detaylı

Sunum İçeriği. Programlamaya Giriş 22.03.2011

Sunum İçeriği. Programlamaya Giriş 22.03.2011 Programlamaya Giriş Nesne Tabanlı Programlamaya Giriş ve FONKSİYONLAR Sunum İçeriği Nesne Tabanlı Programlama Kavramı Fonksiyon tanımlama ve kullanma Formal Parametre nedir? Gerçel Parametre nedir? Fonksiyon

Detaylı

Özyineleme (Recursion)

Özyineleme (Recursion) C PROGRAMLAMA Özyineleme (Recursion) Bir fonksiyonun kendisini çağırarak çözüme gitmesine özyineleme (recursion), böyle çalışan fonksiyonlara da özyinelemeli (recursive) fonksiyonlar denilir. Özyineleme,

Detaylı

Temel Bilgisayar Programlama Final Sınavı Çalışma Notları

Temel Bilgisayar Programlama Final Sınavı Çalışma Notları Diziler Temel Bilgisayar Programlama Final Sınavı Çalışma Notları (Dr. Övünç ÖZTÜRK, Dr. Tahir Emre KALAYCI) (İnşaat Mühendisliği ve Gıda Mühendisliği Grupları İçin) Diziler aynı türden bilgileri saklamak

Detaylı

VERİ YAPILARI VE PROGRAMLAMA (BTP104)

VERİ YAPILARI VE PROGRAMLAMA (BTP104) VERİ YAPILARI VE PROGRAMLAMA (BTP104) Yazar: Doç.Dr. İ. Hakkı CEDİMOĞLU S1 SAKARYA ÜNİVERSİTESİ Adapazarı Meslek Yüksekokulu Bu ders içeriğinin basım, yayım ve satış hakları Sakarya Üniversitesi ne aittir.

Detaylı

ALGORİTMA VE PROGRAMLAMA I

ALGORİTMA VE PROGRAMLAMA I ALGORİTMA VE PROGRAMLAMA I Yrd. Doç. Dr. Deniz KILINÇ [email protected] YZM 1101 Celal Bayar Üniversitesi Hasan Ferdi Turgutlu Teknoloji Fakültesi Genel Bakış 2 Koşul Karşılaştırma Operatörleri Mantıksal

Detaylı

Algoritma ve Programlamaya Giriş

Algoritma ve Programlamaya Giriş Algoritma ve Programlamaya Giriş Algoritma Bir sorunu çözebilmek için gerekli olan sıralı ve mantıksal adımların tümüne Algoritma denir. Doğal dil ile yazılabilir. Fazlaca formal değildir. Bir algoritmada

Detaylı

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Uzaktan Eğitim Uygulama ve Araştırma Merkezi JAVA PROGRAMLAMA Öğr. Gör. Utku SOBUTAY İÇERİK 2 Java Kodlarına Yorum Satırı Eklemek Java Paket Kavramı Java Kütüphane Kavramı Konsoldan Veri Çıkışı ve JOPtionPane Kütüphanesi JOptionPane Kütüphanesi Kullanarak

Detaylı

Veri Yapıları ve Algoritmalar

Veri Yapıları ve Algoritmalar 1 Ders Not Sistemi Vize : % 40 Final : % 60 Kaynaklar Kitap : Veri Yapıları ve Algoritma Temelleri Yazar: Dr. Sefer KURNAZ Internet Konularla ilgili web siteleri 2 Algoritma : «Belirli bir problemin çözümünde

Detaylı

Bit, Byte ve Integer. BIL-304: Bilgisayar Mimarisi. Dersi veren öğretim üyesi: Dr. Öğr. Üyesi Fatih Gökçe

Bit, Byte ve Integer. BIL-304: Bilgisayar Mimarisi. Dersi veren öğretim üyesi: Dr. Öğr. Üyesi Fatih Gökçe Bit, Byte ve Integer BIL-304: Bilgisayar Mimarisi Dersi veren öğretim üyesi: Dr. Öğr. Üyesi Fatih Gökçe Ders kitabına ait sunum dosyalarından adapte edilmiştir: http://csapp.cs.cmu.edu/ Adapted from slides

Detaylı

Toplama işlemi için bir ikili operatör olan artı işareti aynı zamanda tekli operatör olarak da kullanılabilir.

Toplama işlemi için bir ikili operatör olan artı işareti aynı zamanda tekli operatör olarak da kullanılabilir. www.csharpturk.net Türkiye nin C# Okulu Yazar Yunus Özen Eposta [email protected] Tarih 08.04.2006 Web http://www.yunusgen.tr ARİTMETİK OPERATÖRLER VE KULLANIM ŞEKİLLERİ Bilgisayarlar yapıları gereği,

Detaylı

Bilgisayar Teknolojileri Bölümü Bilgisayar Programcılığı Programı. Öğr. Gör. Cansu AYVAZ GÜVEN

Bilgisayar Teknolojileri Bölümü Bilgisayar Programcılığı Programı. Öğr. Gör. Cansu AYVAZ GÜVEN Bilgisayar Teknolojileri Bölümü Bilgisayar Programcılığı Programı Öğr. Gör. Cansu AYVAZ GÜVEN NESNE TABANLI PROGRAMLAMA Java Değişkenler ve Veri Tipleri Operatörler JAVA Java Java SUN bilgisayar şirketince

Detaylı

Prolog da Veri Türleri. Prolog la 4.Hafta. Atom lar (2) Atom lar (1)

Prolog da Veri Türleri. Prolog la 4.Hafta. Atom lar (2) Atom lar (1) Prolog da Veri Türleri Prolog la 4.Hafta Prolog bir veri türünü onun şeklinden tanır. Prolog herhangi bir veri tanımına ihtiyaç duymaz. 2 Atom lar (1) Atom lar aşağıdakilerde oluşan string lerdir. Büyük

Detaylı

Regular Expressions Version 0.1

Regular Expressions Version 0.1 Regular Expressions Version 0.1 Hüseyin Kaya [email protected] 2001 Özet Bu belge Linux and Unix Shell Programming adlı kitaptan faydalalınarak yazılmıştır. Kitabın yazarı David Tansley. İngilizce bilenler

Detaylı

KAYITLAR BÖLÜM 14. 14.1 Giriş

KAYITLAR BÖLÜM 14. 14.1 Giriş BÖLÜM 14 KAYITLAR 14.1 Giriş Bir kayıt, bir nesneyle ilgili verilerin bir araya getirilmesidir. Öğrenci kayıtları, taşıt kayıtları, stok kayıtları günlük yaşantımızda karşılaştığımız yaygın kayıtlardır.

Detaylı

Dr. Fatih AY Tel: 0 388 225 22 55 [email protected] www.fatihay.net

Dr. Fatih AY Tel: 0 388 225 22 55 fatihay@fatihay.net www.fatihay.net Bilgisayar Programlama Ders 6 Dr. Fatih AY Tel: 0 388 225 22 55 [email protected] www.fatihay.net Fonksiyon Prototipleri Fonksiyon Prototipleri Derleyici, fonksiyonların ilk hallerini (prototiplerini)

Detaylı

Yazılım Çeşitleri. Uygulama Yazılımları. İşletim Sistemleri. Donanım

Yazılım Çeşitleri. Uygulama Yazılımları. İşletim Sistemleri. Donanım Yazılım Yazılım Bilgisayarlar üretildikleri anda içlerinde herhangi bir bilgi barındırmadıkları için bir işlevleri yoktur. Bilgisayarlara belirli yazılımlar yüklenerek işlem yapabilecek hale getirilirler.

Detaylı

3/7/2011. ENF-102 Jeoloji 1. Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Veri Tanımları ve Mantıksal Đşlemler

3/7/2011. ENF-102 Jeoloji 1. Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Veri Tanımları ve Mantıksal Đşlemler Veri Tanımları ve Mantıksal Đşlemler Tekrar -- Değişken Tanımlamaları (Definition) ve Veri Türleri (Data Type) Kullanılacak bütün değişkenlerin kullanılmadan önce C derleyicisine bildirilmeleri gerekir.

Detaylı

Nesne Tabanlı Programlama

Nesne Tabanlı Programlama Nesne Tabanlı Programlama Ders Notu - 1 (Değerler, Değişkenler, İşleçler, Tip Dönüşümleri, Mantıksal Operatörler) Dicle Üniversitesi Mühendislik Fakültesi Elektrik Elektronik Mühendisliği Bölümü 1 Değerler

Detaylı

BİLGİSAYAR MÜHENDİSLİĞİ ALGORİTMA VE PROGRAMLAMA II 2.HAFTA SWİTCH (CASE), SAYAÇLAR, DÖNGÜLER,

BİLGİSAYAR MÜHENDİSLİĞİ ALGORİTMA VE PROGRAMLAMA II 2.HAFTA SWİTCH (CASE), SAYAÇLAR, DÖNGÜLER, BİLGİSAYAR MÜHENDİSLİĞİ ALGORİTMA VE PROGRAMLAMA II 2.HAFTA SWİTCH (CASE), SAYAÇLAR, DÖNGÜLER, C++ İÇİN UFAK HATIRLATMALAR Değişken adları bir harf ile başlamalıdır. (a-z, A-Z). Değişken adı numara içerebilir.

Detaylı

BĠLGĠSAYAR PROGRAMLAMA II C++ Programlamaya GiriĢ http://www.cplusplus.com/doc/tutorial/ Published by Juan Soulié

BĠLGĠSAYAR PROGRAMLAMA II C++ Programlamaya GiriĢ http://www.cplusplus.com/doc/tutorial/ Published by Juan Soulié BĠLGĠSAYAR PROGRAMLAMA II C++ Programlamaya GiriĢ http://www.cplusplus.com/doc/tutorial/ Published by Juan Soulié DERSİN WEB SİTESİ: http://nucleus.istanbul.edu.tr/~bilprog2/ DeğiĢkenler ve Data Türleri

Detaylı

BASİT C PROGRAMLARI Öğr.Gör.Dr. Mahmut YALÇIN

BASİT C PROGRAMLARI Öğr.Gör.Dr. Mahmut YALÇIN BASİT C PROGRAMLARI Öğr.Gör.Dr. Mahmut YALÇIN Basit C Programları: Bir Metni Yazdırmak #include /* program çalışmaya main fonksiyonundan başlar*/ int main() { printf( "C diline hoşgeldiniz!\n"

Detaylı

BİL-142 Bilgisayar Programlama II

BİL-142 Bilgisayar Programlama II BİL-142 Bilgisayar Programlama II (C/C++) Hazırlayan: M.Ali Akcayol Gazi Üniversitesi Bilgisayar Mühendisliği Bölümü Konular Giriş Kontrol Yapıları if Seçme Deyimi if... else Seçme Deyimi while Tekrar

Detaylı

BIL1202 ALGORİTMA VE PROGRAMLAMAYA GİRİŞ (Algoritma Geliştirmek, Satır Kod)

BIL1202 ALGORİTMA VE PROGRAMLAMAYA GİRİŞ (Algoritma Geliştirmek, Satır Kod) 2017-2018 BaharYarıyılı Balıkesir Üniversitesi Endüstri Mühendisliği Bölümü 3 BIL1202 ALGORİTMA VE PROGRAMLAMAYA GİRİŞ (Algoritma Geliştirmek, Satır Kod) Yrd. Doç. Dr. İbrahim Küçükkoç Web: ikucukkoc.baun.edu.tr

Detaylı

Bilgisayar Programlama MATLAB

Bilgisayar Programlama MATLAB What is a computer??? Bilgisayar Programlama MATLAB Prof. Dr. İrfan KAYMAZ What Konular is a computer??? MATLAB ortamının tanıtımı Matlab sistemi (ara yüzey tanıtımı) a) Geliştirme ortamı b) Komut penceresi

Detaylı

Görsel Programlama DERS 03. Görsel Programlama - Ders03/ 1

Görsel Programlama DERS 03. Görsel Programlama - Ders03/ 1 Görsel Programlama DERS 03 Görsel Programlama - Ders03/ 1 Java Dili, Veri Tipleri ve Operatörleri İlkel(primitive) Veri Tipleri İLKEL TİP boolean byte short int long float double char void BOYUTU 1 bit

Detaylı

PROGRAMLAMA ALGORĠTMA

PROGRAMLAMA ALGORĠTMA PROGRAMLAMA Programlama Nedir? Bir iģi yapmak için gerekli iģlemlerin tespit edilmesi, tanımlanması ve bu iģlerin sırasının bilinmesidir. Programlama Basamakları: 1- Problemi Tanıma: Programın programcı

Detaylı

YAPILAR BİRLİKLER SAYMA SABİTLERİ/KÜMELERİ. 3. Hafta

YAPILAR BİRLİKLER SAYMA SABİTLERİ/KÜMELERİ. 3. Hafta YAPILAR BİRLİKLER SAYMA SABİTLERİ/KÜMELERİ 3. Hafta YAPILAR Farklı veri tipindeki bilgilerin bir araya gelerek oluşturdukları topluluklara yapı (structure) denir. Yani yapılar, birbiriyle ilişkili değişkenlerin

Detaylı

Bilgisayarda Programlama. Temel Kavramlar

Bilgisayarda Programlama. Temel Kavramlar Bilgisayarda Programlama Temel Kavramlar KAVRAMLAR Programlama, yaşadığımız gerçek dünyadaki problemlere ilişkin çözümlerin bilgisayarın anlayabileceği bir biçime dönüştürülmesi / ifade edilmesidir. Bunu

Detaylı

Uzaktan Eğitim Uygulama ve Araştırma Merkezi

Uzaktan Eğitim Uygulama ve Araştırma Merkezi JAVA PROGRAMLAMA Öğr. Gör. Utku SOBUTAY İÇERİK 2 Java Veri Tipleri ve Özelilkleri Değişken Tanımlama Kuralları Değişken Veri Tipi Değiştirme (Type Casting) Örnek Kodlar Java Veri Tipleri ve Özelilkleri

Detaylı

Öğr. Gör. Serkan AKSU http://www.serkanaksu.net. http://www.serkanaksu.net/ 1

Öğr. Gör. Serkan AKSU http://www.serkanaksu.net. http://www.serkanaksu.net/ 1 Öğr. Gör. Serkan AKSU http://www.serkanaksu.net http://www.serkanaksu.net/ 1 JavaScript JavaScript Nedir? Nestcape firması tarafından C dilinden esinlenerek yazılmış, Netscape Navigator 2.0 ile birlikte

Detaylı

BİLİŞİM TEKNOLOJİLERİ 6. SINIF DERS NOTLARI 2

BİLİŞİM TEKNOLOJİLERİ 6. SINIF DERS NOTLARI 2 PROGRAMLAMA Bir problemin çözümü için belirli kurallar ve adımlar çerçevesinde bilgisayar ortamında hazırlanan komutlar dizisine programlama denir. Programlama Dili: Bir programın yazılabilmesi için kendine

Detaylı

Endüstri Mühendisliği Bölümü Bilgisayar Programlama Ders Notları

Endüstri Mühendisliği Bölümü Bilgisayar Programlama Ders Notları 8- Turbo Pascal Programlama İle Dosya İşlemleri Dosya işlemleri bilgisayar programlamada verilerin tekrar kullanılması açısından çok önemlidir. Yazılan bilgisayar programlarında elde edilen sonuçlar eğer

Detaylı

Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : dak.

Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : dak. Selçuk Üniversitesi Mühendislik Fakültesi Harita Mühendisliği Bölümü ra Sınavı Test Soruları dı soyadı :... Öğrenci no :... İmza :... Tarih, Süre :13.04.2017 60 dak. Dikkat!!! Soru kitapçığında ve cevap

Detaylı

Algoritmalar ve Programlama. Algoritma

Algoritmalar ve Programlama. Algoritma Algoritmalar ve Programlama Algoritma Algoritma Bir sorunu / problemi çözmek veya belirli bir amaca ulaşmak için gerekli olan sıralı mantıksal adımların tümüne algoritma denir. Algoritma bir sorunun çözümü

Detaylı

ALP OĞUZ ANADOLU LİSESİ EĞİTİM ÖĞRETİM YILI BİLGİSAYAR BİLİMİ DERSİ 2.DÖNEM 2.SINAV ÖNCESİ ÇALIŞMA SORULARI VE YANITLARI

ALP OĞUZ ANADOLU LİSESİ EĞİTİM ÖĞRETİM YILI BİLGİSAYAR BİLİMİ DERSİ 2.DÖNEM 2.SINAV ÖNCESİ ÇALIŞMA SORULARI VE YANITLARI ALP OĞUZ ANADOLU LİSESİ 2017-2018 EĞİTİM ÖĞRETİM YILI BİLGİSAYAR BİLİMİ DERSİ 2.DÖNEM 2.SINAV ÖNCESİ ÇALIŞMA SORULARI VE YANITLARI Doğru yanıtlar kırmızı renkte verilmiştir. 1. Problemlerin her zaman sıradan

Detaylı

BTP 207 İNTERNET PROGRAMCILIĞI I. Ders 8

BTP 207 İNTERNET PROGRAMCILIĞI I. Ders 8 BTP 27 İNTERNET PROGRAMCILIĞI I Ders 8 Değişkenler 2 Tamsayı Değerler (Integer) Tamsayılar, tabanlı (decimal), 8 tabanlı (octal) veya 6 tabanlı (hexadecimal) olabilir. 8 tabanındaki sayıları belirtmek

Detaylı

Nesne Tabanlı Programlama

Nesne Tabanlı Programlama Nesne Tabanlı Programlama Ders Notu - 1 Dicle Üniversitesi Mühendislik Fakültesi Elektrik Elektronik Mühendisliği Bölümü 1 Değerler ve Değişkenler Values & Variables 2 1 Değişkenlerin Özellikleri Tipi

Detaylı

[email protected] http://web.hitit.edu.tr/mustafacosar

mustafacosar@hitit.edu.tr http://web.hitit.edu.tr/mustafacosar Algoritma ve Programlamaya Giriş [email protected] http://web.hitit.edu.tr/mustafacosar İçerik Algoritma Akış Diyagramları Programlamada İşlemler o o o Matematiksel Karşılaştırma Mantıksal Programlama

Detaylı

Dinamik Kodlama. [X] Fusion@6. [X] Yeni Fonksiyon

Dinamik Kodlama. [X] Fusion@6. [X] Yeni Fonksiyon Dinamik Kodlama Ürün Grubu Kategori Versiyon Önkoşulu [X] Fusion@6 [X] Yeni Fonksiyon @6 Uygulama @6 Serisi ürünlerde, kullanıcı arabirimlerinin her yerine eklenen dinamik kodlama özelliği ile, programın

Detaylı

Veri Tabanı-I 2.Hafta

Veri Tabanı-I 2.Hafta Veri Tabanı-I 2.Hafta Varlık-İlişki Modeli ( Entity-Relationship (E-R) Model ) 1 Varlık-İlişki (E-R) Modeli Varlık (Entity) : Diğer nesnelerden ayırt edilebilen tekil (unique) nesnedir. (Soyut (SĠPARĠġ)

Detaylı

ALGORİTMA VE PROGRAMLAMA II

ALGORİTMA VE PROGRAMLAMA II ALGORİTMA VE PROGRAMLAMA II Yrd. Doç. Dr. Deniz KILINÇ [email protected] YZM 1102 Celal Bayar Üniversitesi Hasan Ferdi Turgutlu Teknoloji Fakültesi Genel Bakış 2 Yapılar ve Birlikler enum Deyimi

Detaylı

JAVA DÖNGÜ DEYİMLERİ. For Döngüsü

JAVA DÖNGÜ DEYİMLERİ. For Döngüsü JAVA DÖNGÜ DEYİMLERİ Belirli bir iş bir çok kez tekrarlanacaksa, programda bu iş bir kez yazılır ve döngü deyimleriyle istenildiği kadar tekrarlanabilir. Java da bu işi yapan üç ayrı deyim vardır: while

Detaylı

ORACLE DA KÜRSÖRLER. Gerekli sistem değişkenleri

ORACLE DA KÜRSÖRLER. Gerekli sistem değişkenleri ORACLE DA KÜRSÖRLER Gerekli sistem değişkenleri SQL%ISOPEN : kürsör açıksa değeri true, kapalı ise değeri false SQL%ROWCOUNT : sql ile işlem gören kayıt sayısı bulunur. SQL%FOUND : sql işlemi sonucu, en

Detaylı

/ C Bilgisayar Programlama Final Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak.

/ C Bilgisayar Programlama Final Sınavı Test Soruları. Adı soyadı :... Öğrenci no :... İmza :... Tarih, Süre : , 60 dak. Selçuk Üniversitesi Mühendislik Fakültesi Harita Mühendisliği Bölümü Final Sınavı Test Soruları dı soyadı :... Öğrenci no :... İmza :... Tarih, Süre :09.01.2013, 60 dak. Dikkat!!! Soru kitapçığında ve

Detaylı

TEMEL BİLGİSAYAR BİLİMLERİ. Programcılık, problem çözme ve algoritma oluşturma

TEMEL BİLGİSAYAR BİLİMLERİ. Programcılık, problem çözme ve algoritma oluşturma TEMEL BİLGİSAYAR BİLİMLERİ Programcılık, problem çözme ve algoritma oluşturma Programcılık, program çözme ve algoritma Program: Bilgisayara bir işlemi yaptırmak için yazılan komutlar dizisinin bütünü veya

Detaylı

BİLGİSAYAR BİLİMİ DERSİ (KUR 1) PYTHON PROGRAMLAMA DİLİ ÇALIŞMA KÂĞIDI - 1

BİLGİSAYAR BİLİMİ DERSİ (KUR 1) PYTHON PROGRAMLAMA DİLİ ÇALIŞMA KÂĞIDI - 1 BİLGİSAYAR BİLİMİ DERSİ (KUR 1) PYTHON PROGRAMLAMA DİLİ ÇALIŞMA KÂĞIDI - 1 Ekrana Metin Yazdırmak Ekranda metin yazdırmak istendiğinde print komutu kullanılır. Kullanımı aşağıda verilmiştir. Parantez içinde

Detaylı

Internet Programming II

Internet Programming II Internet Programming II Elbistan Meslek Yüksek Okulu 2016 2017 Bahar Yarıyılı Öğr. Gör. Murat KEÇECĠOĞLU Kontrol deyimleri programlamanın olmazsa olmaz koşullarındandır. Şartlara (karşılaştırma) bağlı

Detaylı