2010-11-03 26 views
5

Tôi đang phát xung quanh với các ràng buộc trong (swi) prolog sử dụng thư viện clpfd.SWI-Prolog và các ràng buộc, thư viện CLP (FD)

Tôi đang cố gắng xác định khi nào một tập hợp các ràng buộc đóng gói hoặc thuê gói khác, ví dụ: X < 4 đóng gói X < 7 như bất cứ khi nào cái cũ là đúng, cái sau là đúng. Điều này có thể dễ dàng được biểu diễn bằng cách sử dụng hàm ý logic. Tuy nhiên, tôi không thể có được toán tử # ==> cho tôi kết quả mong muốn, vì vậy tôi đã sử dụng không (Co1 #/\ # \ Co2) trong đó Co1 và Co2 là những ràng buộc. Điều này là tốt cho các ràng buộc cá nhân, nhưng sau đó tôi muốn chuyển một liên kết của các ràng buộc vào Co1 và Co2.

Bây giờ, đây là chà. Khi tôi cố gắng

X#<7 #/\ #\X#<4. 

tôi nhận được lại

X in 4..6, 
X+1#=_G822, 
X+1#=_G834, 
_G822 in 5..7, 
_G834 in 5..7. 

(kỳ quặc đủ, làm điều này trong kết quả Sicstus trong một lỗi segmentation)

Khi tôi vượt qua trong

X#<7,X#<4 

tôi nhận được mong muốn

X in inf..3. 

Rõ ràng, tôi không thể chuyển phần sau vào không (Co1 #/\ # \ Co2), nhưng trước đây không cho tôi kết quả tôi muốn. Bất cứ ai có thể giải thích lý do tại sao hai phương pháp tiếp cận mang lại kết quả khác nhau, và làm thế nào tôi có thể có được cựu hành động như sau này?

Trả lời

2

Dường như bạn đang giao dịch với CLP (FD). Những người giải quyết này phân biệt giai đoạn thiết lập và giai đoạn ghi nhãn để giải quyết một vấn đề ràng buộc.

Bộ giải mã CLP (FD) không làm giảm hoàn toàn sự cố trong giai đoạn thiết lập. Vì nó có cơ hội giảm phạm vi biến đổi trong giai đoạn ghi nhãn. Vì vậy, có thể là trong quá trình thiết lập một vấn đề được đặt ra có thể được giảm bởi các trình giải quyết khác thành "Không", nhưng nó sẽ không có bộ giải mã CLP (FD). Chỉ khi ghi nhãn "Không" sẽ được phát hiện.

Giảm bao nhiêu được thực hiện trong giai đoạn thiết lập phụ thuộc rất lớn vào hệ thống CLP (FD) đã cho. Một số hệ thống CLP (FD) giảm nhiều hơn trong giai đoạn thiết lập, trong khi các hệ thống khác thì giảm đi. Ví dụ, GNU Prolog sử dụng một số tuyên truyền lập chỉ mục, trong khi SWI Prolog thì không.Vì vậy, chúng ta thấy ví dụ, không ví dụ của bạn:

SWI-Prolog:

?- X #< Y, Y #< Z, Z #< X. 
Z#=<X+ -1, 
X#=<Y+ -1, 
Y#=<Z+ -1. 

GNU Prolog:

?- X #< Y, Y #< Z, Z #< X. 
(7842 ms) no 

Hơn nữa kể từ khi bạn đang sử dụng chế reified nó cũng phụ thuộc một chút như thế nào thông minh việc cải tổ được thực hiện. Nhưng tôi đoán trong trường hợp hiện tại nó chỉ là vấn đề tuyên truyền. Chúng tôi nhận thấy hiện nay ví dụ của bạn:

SWI-Prolog:

?- X #< 4 #==> X #< 7. 
X+1#=_G1330, 
X+1#=_G1342, 
7#>=_G1330#<==>_G1354, 
_G1354 in 0..1, 
_G1377#==>_G1354, 
_G1377 in 0..1, 
4#>=_G1342#<==>_G1377. 

GNU Prolog:

?- X #< 4 #==> X #< 7. 
X = _#22(0..268435455) 

Có một sự cân bằng giữa làm giảm nhiều trong giai đoạn thiết lập và để lại làm việc nhiều hơn đến giai đoạn ghi nhãn. Và toàn bộ vấn đề cũng phụ thuộc vào ví dụ đã cho. Nhưng khi bạn cũng đã ghi nhãn bên cạnh thiết lập, bạn sẽ không thấy bất kỳ sự khác biệt về kết quả:

SWI-Prolog:

?- X in 0..9, X #< 4 #==> X #< 7, label([X]). 
X = 0 ; 
X = 1 ; 
X = 2 ; 
X = 3 ; 
X = 4 ; 
X = 5 ; 
X = 6 ; 
X = 7 ; 
X = 8 ; 
X = 9. 

GNU Prolog:

?- fd_domain(X,0,9), X #< 4 #==> X #< 7, fd_labeling([X]). 
X = 0 ? ; 
X = 1 ? ; 
X = 2 ? ; 
X = 3 ? ; 
X = 4 ? ; 
X = 5 ? ; 
X = 6 ? ; 
X = 7 ? ; 
X = 8 ? ; 
X = 9 

tôi đã không kiểm tra với SICStus Prolog hoặc B-Prolog. Nhưng tôi đoán họ sẽ cư xử ở đâu đó trong tính hợp lý của SWI-Prolog và GNU Prolog.

CLP (Q) không thực sự thay thế nếu tên miền của bạn thực sự là FD, vì nó sẽ bỏ lỡ một số "Không" giảm, mà CLP (FD) sẽ không bỏ lỡ. Ví dụ sau đây là không thể thoả mãn trong CLP (FD), nhưng satisfiable trong CLP (Q):

X = Y + 1, Y < Z, Z < X. 

Bye

4

Việc áp dụng các ràng buộc số học chung so với số nguyên là không thể xác định nói chung, vì vậy tất cả các trình giải mã chính xác đều có giới hạn cố hữu vượt quá giới hạn của chúng. Nếu bạn biết tên miền của mình là hữu hạn, bạn có thể đăng các tên miền và sau đó cố gắng tìm các mẫu đối sánh sẽ làm cho hàm ý không hợp lệ, sử dụng thuộc tính ghi nhãn/2 của trình giải quyết ràng buộc. Cũng xem xét rằng sự bất bình đẳng tuyến tính trên Q là decidable, và thư viện SWI-Prolog (clpq) là hoàn chỉnh cho chúng. Do đó, bạn có thể thử các ràng buộc của mình trong CLP (Q) với:

?- use_module(library(clpq)). 
true. 

?- { X < 4, X >= 7 }. 
false. 

và thấy rằng không có ví dụ nào tồn tại trong Q (do đó cũng không phải trong Z), và do đó hàm ý giữ.

+0

Rất cám ơn, tôi đang đối phó với sự bất bình đẳng tuyến tính. Tôi đang cố gắng tự động tìm phạm vi cho một tập hợp các ràng buộc liên kết (có thể phủ định). Vì vậy, tôi muốn có thể vượt qua (ví dụ) X # <4,\#(X#> 2), hoạt động. Tôi cũng muốn truyền đạt điều phức tạp hơn, ví dụ: X # <4,#\\(X#> 2, X # <1), không hoạt động, vì # \ sau đó được coi là toán tử nhị phân. Tương tự, cho nó X # <4,#\\((X#> 2, X # <1)) cũng dẫn đến lỗi. – Nir

+1

Để hủy kết hợp, bạn phải sử dụng #/\, ví dụ: # \ (A #/\ B). – mat

Các vấn đề liên quan