前言
如果你是一位prolog的新手,希望你首先閱讀這篇文章,好對(duì)prolog的全局有個(gè)了解,本文將詳細(xì)介紹prolog學(xué)習(xí)流程編程思路上以及prolog語(yǔ)法細(xì)節(jié)。
首先,問(wèn)一個(gè)基礎(chǔ)的問(wèn)題:我們已經(jīng)在Prolog程序中看到了很多類(lèi)型的表達(dá)式(比如,jody,playsAirGuitar(mia),和X),但這些僅僅只是例子,是時(shí)候更加深入了,到底事實(shí)、規(guī)則和查詢是由什么構(gòu)成的?
答案就是語(yǔ)句(terms),在Prolog中一共存在四種類(lèi)型的語(yǔ)句:原子,數(shù)字,變量和復(fù)雜語(yǔ)句(或者稱為結(jié)構(gòu)).原子和數(shù)字統(tǒng)稱為常量,常量和變量統(tǒng)稱簡(jiǎn)單語(yǔ)句.
首先要明確基礎(chǔ)的字符的范圍:大寫(xiě)字母:A,B,...,Z;小寫(xiě)字母:a,b,...,z;數(shù)字:0,1,2,...,9.另外還包括“_”,即英文下劃線字符;和其他一些特殊英文字符,比如:+,-,*,/,《,》,=,:,.,&,~;空格也是字符,但是不常用,并且也不可見(jiàn).字符串是指沒(méi)有切斷的字符序列.
原子(Atoms)
一個(gè)原子是以下情況之一:
1. 由字符構(gòu)成的字符串,其中有效字符包括:大字字母,小寫(xiě)字母,數(shù)字,和下劃線,并且是小寫(xiě)字母作為頭字符.一些例子:butch,big_kahuna_burger,listen2Music,playsAirGuitar.
2. 使用單引號(hào)封裝的字符序列.比如:‘Vincent’,‘The Gimp’,‘Five_Dollar_Shake’,‘&^%%@# *’,‘ ’.被單引號(hào)封裝的字符序列被稱為原子名.注意我們已經(jīng)使用了空格字符,
事實(shí)上,使用單引號(hào)封裝,其中的一個(gè)作用就是可以在原子中精確地使用類(lèi)似空格字符這樣的特殊字符.
3. 特殊字符組成的字符串.比如:@=,====》,;,:-等都是原子.正如我們看到的,一些特殊原子,比如;(邏輯或),:-(規(guī)則中連接頭部和主干的符號(hào))已經(jīng)有預(yù)定義的含義.
數(shù)字(Numbers)
在典型的Prolog程序中,實(shí)數(shù)并不是很有用武之地.所以雖然大多數(shù)Prolog的實(shí)現(xiàn)都支持浮點(diǎn)數(shù),但是本文不討論.
但是整數(shù)(比如:-2,-1,0,1,2,...)卻十分有用,比如在計(jì)算列表的元素?cái)?shù)目之類(lèi)的工作時(shí)候,我們將會(huì)在第5章詳細(xì)介紹.Prolog中數(shù)字的表示很簡(jiǎn)單,沒(méi)有什么特殊,如下:
23, 1001, 0, -365, 等等.
變量(Variables)
變量是由大寫(xiě)字母,小寫(xiě)字母,數(shù)字和下劃線組成的字符串,并且頭字母必須是大寫(xiě)字母或者下劃線.比如:
X, Y, Variable, _tag, X_526, List, List24, _head, Tail, _input, Output
都是Prolog中有效的變量.變量”_“是一個(gè)特例,它被稱為匿名變量,我們將會(huì)在第4章中介紹.
復(fù)雜語(yǔ)句(Complex Terms)
常量,數(shù)字,和變量都是構(gòu)建語(yǔ)句的模塊,現(xiàn)在我們學(xué)習(xí)如何將它們組成復(fù)雜語(yǔ)句.復(fù)雜語(yǔ)句也稱為結(jié)構(gòu)體.
復(fù)雜語(yǔ)句由一個(gè)函子(functor,也可以理解為函數(shù)名)和一個(gè)參數(shù)序列構(gòu)成.參數(shù)序列放在小括號(hào)內(nèi),由英文逗號(hào)分隔,并且是放在函子后面.請(qǐng)注意函子后面必須緊跟參數(shù)序列,
中間不能有空格.函子必須是一個(gè)原子,即,變量不能用作函子.另一方面,參數(shù)序列可以是任何類(lèi)型的語(yǔ)句.
從KB1到KB5,我們已經(jīng)看到了許多復(fù)雜語(yǔ)句的例子.比如,playsAirGuitar(jody)就是一個(gè)復(fù)雜語(yǔ)句,其中playsAirGuitar是函子,jody是參數(shù)序列(只有一個(gè)參數(shù)).另一個(gè)
例子是loves(vincent, mia),loves是函子,vincent和mia是參數(shù)序列;再比如一個(gè)包含了變量的例子:jealous(marsellus, W).
(注:函子和謂詞由一定區(qū)別,我的理解是:函子是謂詞的名字,謂詞包含了函子及其參數(shù)序列,是整個(gè)邏輯的實(shí)現(xiàn)統(tǒng)一體.)
但是,復(fù)雜語(yǔ)句的定義可以允許更為復(fù)雜的情況.事實(shí)上,在復(fù)雜語(yǔ)句中,也可以內(nèi)嵌其他復(fù)雜語(yǔ)句(就是說(shuō),復(fù)雜語(yǔ)句允許遞歸).比如:
hide(X, father(father(father(butch)))).
就是一個(gè)完美的符合定義的復(fù)雜語(yǔ)句.它的函子是hide,有兩個(gè)參數(shù):一個(gè)是變量X,另外一個(gè)是復(fù)雜語(yǔ)句,father(father(father(butch))).這個(gè)復(fù)雜語(yǔ)句組成是:函子是father,
另外一個(gè)復(fù)雜語(yǔ)句,father(father(butch))是其唯一的參數(shù).里層的復(fù)雜語(yǔ)句的參數(shù)依然是一個(gè)復(fù)雜語(yǔ)句:father(butch).但是到了嵌套的最里層,參數(shù)就是一個(gè)常量:butch.
實(shí)際上,這種嵌套(遞歸結(jié)構(gòu))使得我們可以自然地描述很多問(wèn)題,而且這種遞歸結(jié)構(gòu)和變量合一之間的互相作用,正是Prolog強(qiáng)有力的武器.
復(fù)雜語(yǔ)句的參數(shù)個(gè)數(shù)稱為元數(shù)(arity).比如,woman(mia)是一個(gè)元數(shù)為1的復(fù)雜語(yǔ)句,loves(vincent, mia)是一個(gè)元數(shù)為2的復(fù)雜語(yǔ)句.
元數(shù)對(duì)于Prolog很重要.Prolog允許定義函子相同但是元數(shù)不同的復(fù)雜語(yǔ)句.比如,我們可以定義兩個(gè)參數(shù)的loves謂詞,loves(vincent, mia);也可以定義三個(gè)參數(shù)的loves謂詞,
loves(vincent, marsellus, mia).如果我們這么做了,Prolog會(huì)認(rèn)為這兩個(gè)謂詞是不同的.在第5章中,我們將會(huì)看到定義相同函子但是元數(shù)不同的具體應(yīng)用.
當(dāng)我們需要提及定義的謂詞,介紹如何使用它們的時(shí)候(比如,在文檔中),慣例是”函子/元數(shù)“這種形式.回到KB2,我們有三個(gè)謂詞,之前的表達(dá)如下:
listen2Music
happy
playsAirGuitar
使用正式的書(shū)寫(xiě)方式如下:
listen2Music/1
happy/1
playsAirGuitar/1
Prolog不會(huì)因?yàn)槎x了兩個(gè)loves謂詞而迷惑,它會(huì)區(qū)分loves/2和loves/3是不同的謂詞.
評(píng)論