Flowmode 宣告
在 Prolog 中程式設計時,並不總是可能或者希望建立為每個可能的引數組合統一的謂詞。例如,謂詞 between(X,Y,Z)
表示 Z 在數字上位於 X 和 Y 之間。在 X,Y 和 Z 全部繫結的情況下(Z 在 X 和 Y 之間或者不是),或者在哪裡,很容易實現謂詞 between(X,Y,Z)
。X 和 Y 是繫結的,Z 是自由的(Z 與 X 和 Y 之間的所有數字統一,或者如果 Y <X 則謂詞失敗); 但在其他情況下,例如 X 和 Z 被繫結而 Y 是自由的,可能存在無限數量的統一。雖然這可以實現,但通常不會。
流宣告或模式宣告允許顯式描述謂詞在使用繫結引數的不同組合呼叫時的行為方式。在 between
的情況下,宣告將是:
%! between(+X,+Y,+Z) is semidet.
%! between(+X,+Y,-Z) is nondet.
每行指定謂詞的一個潛在呼叫模式。每個引數都用+
來裝飾,以指示它被繫結的情況,或者 -
來指示它不存在的情況(還有其他裝飾可用於更復雜的型別,例如可能部分繫結的元組或列表)。關鍵字 after 是表示該情況下謂詞的行為,可能是以下之一:
det
如果謂詞總是成功而沒有選擇點。例如add(+X,+Y,-Z)
是det
,因為新增兩個給定數字 X 和 Y 將始終只有一個答案。semidet
如果謂詞成功或失敗,沒有選擇點。如上所述,between(+X,+Y,+Z)
是semidet
,因為 Z 在 X 和 Y 之間或者不是。multi
如果謂詞總是成功,但可能有選擇點(但也可能沒有)。例如,factor(+X,-Y)
將是multi
,因為一個數字總是至少有一個因子 - 本身 - 但可能有更多。nondet
如果謂詞可能選擇點成功,或者失敗。例如,between(+X,+Y,-Z)
是nondet
,因為在 X 和 Y 之間可能存在 Z 與數字的幾種可能的統一,或者如果 Y <X 則它們之間沒有數字並且謂詞失敗。
流/模式宣告也可以與引數標籤結合使用,以闡明術語的含義或鍵入內容。例如,between(+From:Int, +To:Int, +Mid:Int) is semidet
。
在純 Prolog 中,流和模式宣告是可選的,僅用於文件生成,但它們對於幫助程式設計師識別例項化錯誤的原因非常有用。
在 Mercury 中,流和模式宣告(和型別)是必需的,並由編譯器驗證。使用的語法如上所述。
在 Visual Prolog 中,流和模式宣告和型別也是必需的,語法也不同。上述宣告將寫成:
between : (int From, int To, int Mid) determ (i,i,i) nondeterm (i,i,o).
含義與上述相同,但區別在於:
- 流/模式宣告與型別宣告分開(因為假設單個謂詞的流/模式不會隨型別過載而變化);
i
和o
用於+
和-
,並與基於排序的引數匹配;- 使用的術語不同。
det
變成procedure
,semidet
變成determ
,nondet
變成nondeterm
(multi
仍然是multi
)。