gpt4 book ai didi

prolog - SWI-Prolog CLPFD

转载 作者:行者123 更新时间:2023-12-01 09:47:47 25 4
gpt4 key购买 nike

我是约束编程的 prolog 新手。我有一个 CLPFD 没有像我期望的那样减少域的问题。这可能真的很简单。

 [A,B] ins 1..5,A*B#=5.

我希望它将 A 和 B 的域减少到
1\/5

但它只是给
A in 1..5,
A*B#=5,
B in 1..5.

任何建议,将不胜感激。

最佳答案

虽然这个答案是为 量身定做的如在 中实现,想法/方法是可移植的。

:- use_module(library(clpfd)).

Here's how we can reduce domain sizes before starting full enumeration:

shave_zs(Zs) :-
maplist(flag_zs_shave_z(F,Zs), Zs),
once((var(F) ; ground(Zs) ; shave_zs(Zs))).

flag_zs_shave_z(Flag, Zs, Z) :-
( fd_size(Z, sup)
-> true % never shave the infinite
; fd_dom(Z, Z_dom),
phrase(dom_integers_(Z_dom), Z_vals),
maplist(flag_zs_z_val(Flag,Zs,Z), Z_vals)
).

flag_zs_z_val(Flag, Zs, Z, Z_val) :-
( \+ call_with_inference_limit((Z #= Z_val,labeling([],Zs)), 1000, _)
-> Z #\= Z_val,
Flag = true
; true
).

我们使用语法 dom_integers_//1 , 定义在 SWI-Prolog clpfd manual page :
dom_integers_(I)      --> { integer(I) }, [I].
dom_integers_(L..U) --> { numlist(L, U, Is) }, Is.
dom_integers_(D1\/D2) --> dom_integers_(D1), dom_integers_(D2).

示例查询:
?- [A,B] ins 1..5,  A*B #= 5,  (Shaved = false ; Shaved = true, shave_zs([A,B])).
Shaved = false, A*B #= 5, A in 1..5, B in 1..5 ;
Shaved = true, A*B #= 5, A in 1\/5, B in 1\/5.

?- [A,B] ins 1..10, A*B #= 10, (Shaved = false ; Shaved = true, shave_zs([A,B])).
Shaved = false, A*B #= 10, A in 1..10 , B in 1..10 ;
Shaved = true, A*B #= 10, A in 1..2\/5\/10, B in 1..2\/5\/10.

关于prolog - SWI-Prolog CLPFD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33184434/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com