2017-09-25 30 views
2

我剛剛開始學習Prolog的,我發現一些代碼,我也很難理解:序言 - 新來的Prolog,有一個很難理解一個代碼塊

stringCounter([],0,0). 
stringCounter([H|[]],1,1) :- char_type(H, alpha),!. 
stringCounter([H1,H2|T],CCount,WCount):- 
     char_type(H1, alpha), 
     \+char_type(H2,alpha), 
     !, 
     stringCounter(T,L0,A0), 
     CCount is L0+1, WCount is A0+1. 

stringCounter([H|T],CCount,WCount):- 
     char_type(H, alpha), 
     !, 
     stringCounter(T,L1,A1), 
     CCount is L1+1, WCount is A1+0. 

stringCounter([_|T],CCount,WCount):- !, stringCounter(T,CCount,WCount). 

的功能任務是計算字符串中有多少個字符,以及有多少個字符(據我瞭解)。

我瞭解的大多數代碼在這裏除了3件小事:

  1. 如何CCount is L0+1, WCount is A0+1等有效的語法? L0A0是完全未定義的。 Prolog如何知道例如A0+1是什麼?不應該是A0 is WCount + 1

  2. 我不明白stringCounter([H|[]],1,1) :- char_type(H, alpha),!.stringCounter([_|T],CCount,WCount):- !, stringCounter(T,CCount,WCount).的目的是什麼。

  3. 爲什麼如果我將stringCounter([_|T],CCount,WCount):- !, stringCounter(T,CCount,WCount).從底部(向上)移開,函數的結果會發生變化?我嘗試過,並且在移動該行後得到了完全不同的結果。

對不起,基本的/愚蠢的問題,但我真的很難包裝我的頭圍繞Prolog和邏輯編程。

回答

2

函數的任務是計算字符串中有多少個字符,以及有多少字(據我瞭解)。

CCount(第二個參數)與統一的alpha字符的數目,和用WCountalpha的字符序列的數目相結合。 Soo 'foo8bar_qux'CCount=9WCount=3統一。

CCount is L0+1,WCount is A0+1等是一個有效的語法? L0A0完全未定義。 (..)

他們是?上面這條線一號線,我們可以看到:

stringCounter(T,L0,A0), 

所以它是由stringCounter接地L0A0。如果在stringCounter/3調用後L0A0停止接地,那麼它會正常工作。你是正確的,Prolog不能用is/2謂詞處理不相關的變量。

我不明白stringCounter([H|[]],1,1) :- char_type(H, alpha),!.stringCounter([_|T],CCount,WCount):- !, stringCounter(T,CCount,WCount).的目的是什麼。

[H|[]][H]冗長形式:用一種元素[H]列表。在這裏,我們檢查H是否是字母字符。如果是,那麼我們把它算作一個(對於CCountWCount)。請注意,它以剪輯!)結束。這意味着其他子句被忽略。

該語句stringCounter([_|T],CCount,WCount):- !, stringCounter(T,CCount,WCount).是最後一個。由於其他子句使用剪切,這意味着該子句僅在列表包含至少一個元素的情況下觸發,並且該元素不是alpha。在這種情況下,我們就尾遞歸調用,並且不計的字符(bouth CCountWCount

爲什麼功能變化的結果,如果我移動stringCounter([_|T],CCount,WCount) :- !, stringCounter(T,CCount,WCount).遠離底部(向上)?我嘗試了,我得到了一個完全不同的結果後,我搬到了該行。

因爲在此之前正如所說,stringCounter([_|T],CCount,WCount)頭與每一個非空列表相匹配。這是因爲在條款裁員的唯一在那之上,它被隱含地保護只接受非alpha字符,等等。

所以萬一你把它移到頂端。它可能會導致所有的字符串都有CCount=0WCount=0,因爲它會遞歸地枚舉字符串直到達到結尾,在這種情況下,它將與基本結合stringCounter([],0,0)一致。 Cut's可以使程序更高效,但是由於一個子句的規範影響該子句下面的子句,因此它們使得程序不易理解。