亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將約束變量與`length / 2`一起使用

將約束變量與`length / 2`一起使用

小唯快跑啊 2019-11-20 14:54:14
這是問題所在:$ swiplWelcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.6-5-g5aeabd5)Copyright (c) 1990-2015 University of Amsterdam, VU AmsterdamSWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,and you are welcome to redistribute it under certain conditions.Please visit http://www.swi-prolog.org for details.For help, use ?- help(Topic). or ?- apropos(Word).?- use_module(library(clpfd)).true.?- N in 1..3, length(L, N).N = 1,L = [_G1580] ;N = 2,L = [_G1580, _G1583] ;N = 3,L = [_G1580, _G1583, _G1586] ;ERROR: Out of global stack % after a while(我可以切換子查詢的順序,結果是一樣的)。我想我需要貼標簽N才能使用它,但是我想知道是什么問題?我以前沒有設法cho縮length/2。前言 clpfd
查看完整描述

3 回答

?
www說

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)


查看完整回答
反對 回復 2019-11-20
?
海綿寶寶撒

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]

...%未終止(按預期)


查看完整回答
反對 回復 2019-11-20
?
GCT1015

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而言“根本失敗”。對于在那些系統中,不會由于當前表示的耗盡而導致意外故障。也就是說,他們的失敗總是可以被視為誠實。


查看完整回答
反對 回復 2019-11-20
  • 3 回答
  • 0 關注
  • 655 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號