3 回答

TA貢獻1775條經驗 獲得超8個贊
length/2適當的列表長度約束可能比不確定性稍強的有用。你可以找到一個日食實現它在這里,所謂的len/2。這樣,您將獲得以下行為:
?- N :: 1..3, len(Xs, N).
N = N{1 .. 3}
Xs = [_431|_482] % note it must contain at least one element!
There is 1 delayed goal.
Yes (0.00s cpu)
然后,您可以通過枚舉來枚舉有效列表N:
?- N :: 1..3, len(Xs, N), indomain(N).
N = 1
Xs = [_478]
Yes (0.00s cpu, solution 1, maybe more)
N = 2
Xs = [_478, _557]
Yes (0.02s cpu, solution 2, maybe more)
N = 3
Xs = [_478, _557, _561]
Yes (0.02s cpu, solution 3)
或通過生成具有良好舊標準的列表length/2:
?- N :: 1..3, len(Xs, N), length(Xs, _).
N = 1
Xs = [_488]
Yes (0.00s cpu, solution 1, maybe more)
N = 2
Xs = [_488, _555]
Yes (0.02s cpu, solution 2, maybe more)
N = 3
Xs = [_488, _555, _636]
Yes (0.02s cpu, solution 3)

TA貢獻1809條經驗 獲得超8個贊
以下基于clpfd和meta-predicate的巴洛克式變通辦法如何? tcount/3
:-use_module([ library(clpfd),library(lambda) ])。
list_FDlen(Xs,N):-
tcount(\ _ ^ =(true),Xs,N)。
讓我們查詢!
1..3中的?-N,list_FDlen(Xs,N)。
N = 1,Xs = [_A]
; N = 2,Xs = [_A,_B]
; N = 3,Xs = [_A,_B,_C]
; 假。%普遍終止
?.2中的?-N,list_FDlen(Xs,N)。
N = 0,Xs = []
; N = 1,Xs = [_A]
; N = 2,Xs = [_A,_B]
; 假。%也普遍終止
那這個特定的查詢呢?
?-2..sup中的N,list_FDlen(Xs,N)。
N = 2,Xs = [_A,_B]
; N = 3,Xs = [_A,_B,_C]
; N = 4,Xs = [_A,_B,_C,_D]
...%未終止(按預期)

TA貢獻1827條經驗 獲得超4個贊
讓我們從最明顯的一個開始。如果您切換目標,那么您將:
?- length(L, N), N in 1..3.
具有與以下相同的終止屬性:
? -長度(L,N),假,N的1..3。
因此很明顯,這一定不能以Prolog的執行機制終止。
但是,如果放在N in 1..3前面,則可能會影響終止。為此,必須使用有限的手段來證明N從4開始不存在這種情況。您如何在沒有約束的系統中(即僅存在語法統一性)證明這一點?好吧,你不能。而length/2被普遍定義只是沒有約束的存在。隨著library(clpfd)事情是微不足道的,對于N #>= 4, N in 1..3簡單的故障1。還請注意,library(clpfd)與其合作不多library(clpq),可能也很有趣。
結果,您將需要定義自己的長度-對于您感興趣的每個約束包。這有點可惜,但是目前尚無通用的方法可以看到。(((也就是說,如果您有興趣并對此進行了思考,您可能會想出一個不錯的API,每個約束系統都應遵循該API。A,我懷疑這將花費數十年的時間。目前,還有很多差異很大))
所以這是第一種天真的方法fd_length/2:
fd_length([], N) :-
N #= 0.
fd_length([_|L], N0) :-
N0 #>= 1,
N1 #= N0-1,
fd_length(L, N1).
好的,可以對此進行優化以避免不必要的選擇點。但是還有一個更根本的問題:如果要確定length列表的長度N,這將創建N約束變量!但是我們只需要一個。
fd_length(L, N) :-
N #>= 0,
fd_length(L, N, 0).
fd_length([], N, N0) :-
N #= N0.
fd_length([_|L], N, N0) :-
N1 is N0+1,
N #>= N1,
fd_length(L, N, N1).
同樣,由于許多原因,這也不是完美的:它可以像當前系統一樣使用Brent算法;并結合所有fd屬性。同樣,算術表達式可能也不是一個好主意。但我必須(#)/1在SWI中等待...
1:嚴格來說,這僅對SICStus,SWI和YAP而言“根本失敗”。對于在那些系統中,不會由于當前表示的耗盡而導致意外故障。也就是說,他們的失敗總是可以被視為誠實。
- 3 回答
- 0 關注
- 655 瀏覽
添加回答
舉報