我正在搜索一些 SWI-Prolog 函式,該函式能夠將變數設定為內部引數。我的目標是首先創建聯合并在源代碼中進一步定義引數。
意味著例如。我有一些功能union,這個電話union(A, B, A_UNION_B)很有意義。意味著更多的呼叫:
union(A, [1,2], C), A=[3].
結果會給我
C = [3, 1, 2].
uj5u.com熱心網友回復:
(你所說union/3的很可能只是串聯,所以我將使用append/3這個答案來保持簡短。)
如果沒有延遲的目標或限制,您的期望是不可能的。要看到這一點,請考慮以下內容故障片
?- append(A, [1,2], C), false ,A=[3]。 回圈,出乎意料。觀察到的百分比,但對我們來說出乎意料 錯誤的。% 預期,但事實并非如此
為了使整個問題有用,這個查詢必須終止。但是對于 有無數個不同長度的串列A。所以為了描述所有可能的解決方案,我們需要無限多的答案替換,比如
?- 附加(A,[1,2],C)。 A = [],C = [1,2] ; A = [_A],C = [_A,1,2] ; A = [_A,_B], C = [_A,_B,1,2] ; A = [_A,_B,_C], C = [_A,_B,_C,1,2] ; ... .
唯一的辦法是用有限多個答案來描述這組解決方案。一種可能是:
?- when((ground(A);ground(C)), append(A,B,C)).
when((ground(A);ground(C)),append(A,B,C)).
本質上是這樣的:是的,查詢是真的,只要查詢是真的。
雖然這解決了您的確切問題,但它現在會延遲許多其他成功的目標,想想A = [X], B = [].
更精細的版本可以提供更復雜的測驗。但它需要一個與現在不同的定義append/3。一些系統如sicstus-序言提供塊宣告以使其更順利(SWI 對此進行了粗略的模擬)。
所以有可能讓它變得更好,但問題仍然是這是否有意義。畢竟,對于大型程式,除錯延遲目標變得越來越困難。
在許多情況下,最好防止這種情況并產生實體化錯誤,如下所示iwhen/2:
?- iwhen((ground(A);ground(C)),append(A,B,C)).
error(instantiation_error,iwhen/2).
該錯誤可能不是最好的答案,但至少它不是不正確的。它說:您需要提供更多實體化。
如果您真的想針對一般情況解決此問題,則必須深入研究E-unification。這是一個有最瑣碎的問題陳述和極其進化的答案的領域。通常,僅可判定性就不是微不足道的,更不用說有效的演算法了。對于您的特定問題,ACI(用于集合)或 AN lr(用于連接)都是有意義的。在 ACI 需要求解丟番圖方程的地方,單獨的關聯統一甚至比這更復雜。我不知道解決一般問題的 Prolog 系統的任何此類實作。
Prolog IV 為連接提供了一個關聯中綴運算子,但只是延遲了更復雜的情況。所以除錯這些仍然很重要。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/511282.html
標籤:变量序言放联盟
