我正在尝试解决prolog中的约束处理问题.
我需要在10x10的网格中打包4个5x5,4x4,3x3和2x2的正方形.它们可能不重叠.
我的变量看起来像这样:
Name: SqX(i), i=1..10, domain: 1..10
Run Code Online (Sandbox Code Playgroud)
其中X是5,4,3或2.索引i表示行,域表示网格中的列.
我的第一个约束试图定义正方形的宽度和高度.我这样制定它:
Constraint: SqX(i) > SqX(j)-X /\ i>j-X, range: i>0 /\ j>0
Run Code Online (Sandbox Code Playgroud)
这样可能的点被约束在彼此的X行和列之内.然而,Prolog会停止这些约束并给出以下结果:
Adding constraint "(Sq5_I > Sq5_J-5) /\ (I>J-5)" for values:
I=1, J=1,
I=1, J=2,
I=1, J=3,
I=1, J=4,
I=1, J=5,
I=1, J=6,
=======================[ End Solutions ]=======================
Run Code Online (Sandbox Code Playgroud)
所以它停在那里,甚至没有检查其他方块.我的约束很可能太紧张,但我不明白为什么或如何.有什么建议?
现在,我正在学习如何使用C代码连接SICStus Prolog.
我想在SICStus Prolog版本4中使用/使用/查看任意大小的整数的"汉明重量"的C实现.
在我看来,我需要C函数来测试术语类型(SP_is_integer)和C函数来访问Prolog术语(SP_get_integer,SP_get_integer_bytes).
但是,我不确定如何以便携,健壮的方式使用SP_get_integer_bytes.你能指点一些精心设计的C代码做到这一点吗?
我正在研究一个小的prolog应用程序,以解决摩天大楼和栅栏难题.
一个未解决的难题:

一个解决的难题:

当我通过程序已经解决的谜题时,它很快,几乎是即时的,为我验证它.当我通过程序真正的小谜题(例如,2x2,当然有修改的规则),找到解决方案也很快.
问题在于计算具有6x6"原生"大小的谜题.我让它在中止前运行了5个小时左右.太多时间了.
我发现花费时间最长的部分是"围栏",而不是"摩天大楼".分别运行"摩天大楼"可以快速解决问题.
这是我的栅栏算法:
Max,Max- > 1(Max是路径中最后一个顶点的数字.计算通过maximum/2)Max等于(BoardWidth + 1)^2 - NumberOfZeros(BoardWidth+1是沿边缘的顶点数,并NumberOfZeros通过计算count/4).nvalue(Vertices, Max + 1)以确保不同值的数量Vertices是Max(即顶点的路径数)加1(零个值)3并强制路径开始和结束,以提高效率我该怎么做才能提高效率?代码包含在下面以供参考.
skyscrapersinfences.pro
:-use_module(library(clpfd)).
:-use_module(library(lists)).
:-ensure_loaded('utils.pro').
:-ensure_loaded('s1.pro').
print_row([]).
print_row([Head|Tail]) :-
write(Head), write(' '),
print_row(Tail).
print_board(Board, BoardWidth) :-
print_board(Board, BoardWidth, …Run Code Online (Sandbox Code Playgroud) prolog path-finding constraint-programming sicstus-prolog clpfd
我在玩prolog-cooutining谓词freeze/2和frozen/2:
?- freeze(X,a=a), frozen(X,Goal).
?- freeze(X,a=a), freeze(Y,b=b), X=Y, frozen(X,Goal).
Run Code Online (Sandbox Code Playgroud)
sicstus-prolog(x86_64 的 4.5.1 版)给出了这些答案:
| ?- 冻结(X,a=a),冻结(X,目标)。 目标 = prolog:freeze(X,user:(a=a)) , 序言:冻结(X,用户:(a = a))?; 不 | ?- 冻结(X,a=a),冻结(Y,b=b),X=Y,冻结(X,目标)。 Y = X, 目标 = (user:(a=a),prolog:freeze(X,user:(b=b))) , 序言:冻结(X,用户:(a = a)), 序言:冻结(X,用户:(b = b))?; 不
现在没想到!Goal = prolog:freeze(X,user:(a=a))
我所期望的是像swi-prolog 8.0.3 版给出的答案:
?- 冻结(X,a=a),冻结(X,目标)。 目标 = 用户:(a=a) , 冻结(X,a = a)。 ?- 冻结(X,a=a),冻结(Y,b=b),X=Y,冻结(X,目标)。 X = Y, 目标 = (用户:(a=a), 用户:(b=b)) , 冻结(Y,a …
我有一个使用约束在Sicstus Prolog中编写的程序.我的目标是使用标签/ 2和其他一些方法来获得我的变量的随机实例化.
例:
X #> 2, Y #= 2*X, Z #<10
Run Code Online (Sandbox Code Playgroud)
如果我使用
List = [X,Y,Z],
labeling([], List)
Run Code Online (Sandbox Code Playgroud)
获得的第一个结果将是X = Y = Z = 0.您认为返回X,Y和Z的随机值集的最佳方法是什么?
许多Prolog系统都有一个freeze/2谓词,一个应该有名字的谓词,geler/2因为它甚至是在Prolog-II之前发明的.
假设我对同一个变量有条件,但有两个不同的目标,即:
?- freeze(X, G1), freeze(X, G2), X=1.
Run Code Online (Sandbox Code Playgroud)
什么是首选的唤醒策略,G1首先执行还是G2首次执行?如果G1和G2确实会产生新的冻结,这也会被唤醒:
G1 :- freeze(Y, G3), Y=1.
G2 :- freeze(Z, G4), Z=1.
Run Code Online (Sandbox Code Playgroud)
G3或G4是否始终在G1和G2之间执行,或者可能是G1和G2之后执行G3或G4,甚至是以后的任何时间?
再见
在sicstus-prolog上入侵clpz的情况下,我想瞥一眼由SICStus Prolog生成的warren-abstract-machine代码。例如,让我们剖析以下谓词!
is_list([]).
is_list([_|Es]) :- is_list(Es).
Run Code Online (Sandbox Code Playgroud)
这是我现在正在做的事情:
将的2个子句拆分is_list/1为2个单独的谓词,并在其前面加上2个虚拟子句:
is_list__clause1(dummy1)。 %虚拟子句 is_list __clause1([])。 is_list__clause2(dummy2)。 %虚拟子句 is_list __clause2([_ | Es]):-is_list(Es)。
(ab-)使用SICStus prolog顶级,如下所示:
| ?-is_list__clause1(X)。 X =虚拟1t … 0x7eff37281300:GET_NIL_X0 0x7eff37281304:继续 0x7eff37281308:END_OF_CLAUSEQ用户:is_list__clause1 / 1 … | ?-is_list__clause2(X)。 X =虚拟2t … 0x7eff37281150:GET_LIST_X0 0x7eff37281154:U2_VOID_XVAR 1,x(0) 0x7eff37281160:EXECUTEQ用户:is_list / 1 0x7eff37281170:END_OF_CLAUSEQ用户:is_list__clause2 / 1 …
此输出(尽管有些神秘)使我对WAM级别的情况有所了解。我喜欢!
但是必须有一种更简单的方法...请帮助!
问题:用不接触或重叠的正方形(任何大小)填充网格,即使在角落处也不例外。下面和右侧的数字表示填充在相应列/行中的网格方块数。
为了解决这个问题,我应用了以下约束:放置的正方形应该是不相交的,为了确保网格正方形的数量是正确的,我将与给定行/列相交的正方形的长度总和限制为等于该行/列号。
但是,输出的解决方案是 [1, 0, 0, 1] ([NumSquares, X, Y, SquareSize],一个在坐标 (0, 0) 中长度为 1 的正方形,它应该是右图(13 个不同大小和坐标的方块)。
:- use_module(library(clpfd)).
:- include('utils.pl').
solve(Rows, Columns, Vars) :-
% Domain and variables definition
length(Rows, Size),
MaxNumSquares is Size * Size,
NumSquares #>= 0,
NumSquares #< MaxNumSquares,
length(StartsX, NumSquares),
length(StartsY, NumSquares),
length(SquareSizes, NumSquares),
S is Size - 1,
domain(StartsX, 0, S),
domain(StartsY, 0, S),
domain(SquareSizes, 1, Size),
construct_squares(Size, StartsX, StartsY, SquareSizes, Squares),
% Constraints
disjoint2(Squares, [margin(0, 0, 1, 1)]),
lines_constraints(0, Rows, StartsX, SquareSizes), …Run Code Online (Sandbox Code Playgroud) 调度问题有许多系列.我正在研究一个问题,我有一系列的工作/任务,从一个家庭到另一个家庭的过渡需要重新配置机器(设置时间).
我cumulatives[2/3]用来解决这个问题,但我不确定如何表达设置时间.
在这个小例子中,我有10个任务属于3个不同的家庭.任何任务都可以在任何计算机上运行,但是从一个系列中的一个任务切换到另一个系列中的另一个任务需要添加设置时间.
:- use_module(library(clpfd)).
:- use_module(library(lists)).
go( Ss, Es, Ms, Tm, Lab ) :-
Ss = [S1, S2, S3, S4,S5,S6,S7,S8,S9,S10], %Starttimes
Es = [E1, E2, E3, E4,E5,E6,E7,E8,E9,E10], %Endtimeds
Ms = [M1, M2, M3, M4,M5,M6,M7,M8,M9,M10], %MachineIds
domain(Ss, 1, 30),
domain(Es, 1, 30),
domain(Ms, 1, 3 ),
Tasks = [
%Family 1: Setuptime, Su1 = 4,
task( S1, 6, E1, 1, M1 ), %Task T1
task( S2, 6, E2, 1, M2 ), %Task T2
task( S3, 3, E3, 1, …Run Code Online (Sandbox Code Playgroud) prolog constraint-programming job-scheduling sicstus-prolog clpfd
我想了解 SICStus 风格的可扩展统一。在用户手册上的library(atts)规定:
Module:verify_attributes(-Var, +Value, -Goals)钩...
verify_attributes/3可能会调用任意的 Prolog 目标,但Var不应受其约束。绑定Var将导致未定义的行为。
...
在单个统一绑定多个属性变量的情况下,首先撤消所有此类绑定,然后对每个相关变量执行以下操作:
- 对于每个相关模块
M,都会M:verify_attributes/3被调用,收集返回的Goals.- 重做变量绑定。
- 任何
Goals被称为。- 任何在变量上阻塞的目标,现在已经解除阻塞,都会被调用。
到目前为止,我想出了对上述内容的以下解释:
不同的verify_attribute/3处理程序挂钩Var,看到相同的状态Var:所有看到它“pre_unify”。
verify_attribute/3不能绑定Var,但可以绑定其他属性变量。
这些绑定也将被延迟,以便处理程序不仅看到 的相同状态Var,而且看到所有涉及的属性变量。
上面的操作列表需要“5. 强制对属性变量进行任何延迟绑定”。
我是否朝着正确的方向前进 -这就是“完成,然后撤消,然后重做”的全部内容吗? 请帮忙!
prolog ×10
sicstus-prolog ×10
clpfd ×5
c ×1
clpb ×1
constraints ×1
ffi ×1
path-finding ×1
swi-prolog ×1
unification ×1