让序言程序打印出结果而不是布尔值
getting a prolog program to print out results instead of booleans
想象一个具有 6 个区域 R1-R6 的二维地图。每个区域应使用 4 种颜色中的 1 种着色,但相邻区域不能使用相同颜色。
这是我的代码:
% #1 initial facts
next(red,green).
next(red,blue).
next(red,yellow).
next(green,red).
next(green,blue).
next(green,yellow).
next(blue,green).
next(blue,yellow).
next(blue,red).
next(yellow,red).
next(yellow,blue).
next(yellow,green).
% #1 actual program
color(R1,R2,R3,R4,R5,R6).
color(R1,R2,R3,R4,R5,R6):-
% region adjacency relations
next(R1,R2),
next(R1,R3),
next(R1,R4),
next(R2,R4),
next(R2,R5),
next(R3,R4),
next(R3,R6),
next(R4,R5),
next(R4,R6).
预期输出:
R1= red, R2= blue, R3= blue, R4= green, R5= red, R6= red
我的输出:
true
我做错了什么?这甚至是错误的吗?即使我的代码成功找到了正确的颜色配置,我如何让它打印出它的发现?
由于 color/6
的第一个子句,您的程序目前过于笼统。如果您简单地删除第一个子句,您将获得您期望的解决方案(作为许多不同解决方案中的一个)。
还有更漂亮的写法:
regions(Rs):-
Rs = [R1,R2,R3,R4,R5,R6],
% neighbouring regions have different colors
dif(R1, R2),
dif(R1, R3),
dif(R1, R4),
dif(R2, R4),
dif(R2, R5),
dif(R3, R4),
dif(R3, R6),
dif(R4, R5),
dif(R4, R6),
maplist(color, Rs).
color(red).
color(green).
color(blue).
color(yellow).
示例查询和示例解决方案:
?- regions(Rs).
Rs = [red, green, green, blue, red, red] ;
Rs = [red, green, green, blue, red, yellow] ;
Rs = [red, green, green, blue, yellow, red] ;
etc.
请注意使用 dif/2
(prolog-dif) 表示两个术语不同。
对于更严肃的地图着色任务,请考虑使用 clpfd 约束。
如果您的 Prolog 不提供 dif/2,或者您愿意更好地理解这种语言的基础知识,这里可能会更正您的代码:
next(R1,R2) :-
select(R1, [red, green, blue, yellow], Cs),
member(R2, Cs).
color(R1,R2,R3,R4,R5,R6):-
% region adjacency relations
next(R1,R2),
next(R1,R3),
next(R1,R4),
next(R2,R4),
next(R2,R5),
next(R3,R4),
next(R3,R6),
next(R4,R5),
next(R4,R6).
这比使用 dif/2.
在推理计数上稍微更有效
编辑还是更好,用iso_dif/2,或者'old style'版本
next(R1, R2) :- color(R1), color(R2), R1 \= R2.
当然,color/1 来自 mat 的回答
想象一个具有 6 个区域 R1-R6 的二维地图。每个区域应使用 4 种颜色中的 1 种着色,但相邻区域不能使用相同颜色。
这是我的代码:
% #1 initial facts
next(red,green).
next(red,blue).
next(red,yellow).
next(green,red).
next(green,blue).
next(green,yellow).
next(blue,green).
next(blue,yellow).
next(blue,red).
next(yellow,red).
next(yellow,blue).
next(yellow,green).
% #1 actual program
color(R1,R2,R3,R4,R5,R6).
color(R1,R2,R3,R4,R5,R6):-
% region adjacency relations
next(R1,R2),
next(R1,R3),
next(R1,R4),
next(R2,R4),
next(R2,R5),
next(R3,R4),
next(R3,R6),
next(R4,R5),
next(R4,R6).
预期输出:
R1= red, R2= blue, R3= blue, R4= green, R5= red, R6= red
我的输出:
true
我做错了什么?这甚至是错误的吗?即使我的代码成功找到了正确的颜色配置,我如何让它打印出它的发现?
由于 color/6
的第一个子句,您的程序目前过于笼统。如果您简单地删除第一个子句,您将获得您期望的解决方案(作为许多不同解决方案中的一个)。
还有更漂亮的写法:
regions(Rs):-
Rs = [R1,R2,R3,R4,R5,R6],
% neighbouring regions have different colors
dif(R1, R2),
dif(R1, R3),
dif(R1, R4),
dif(R2, R4),
dif(R2, R5),
dif(R3, R4),
dif(R3, R6),
dif(R4, R5),
dif(R4, R6),
maplist(color, Rs).
color(red).
color(green).
color(blue).
color(yellow).
示例查询和示例解决方案:
?- regions(Rs).
Rs = [red, green, green, blue, red, red] ;
Rs = [red, green, green, blue, red, yellow] ;
Rs = [red, green, green, blue, yellow, red] ;
etc.
请注意使用 dif/2
(prolog-dif) 表示两个术语不同。
对于更严肃的地图着色任务,请考虑使用 clpfd 约束。
如果您的 Prolog 不提供 dif/2,或者您愿意更好地理解这种语言的基础知识,这里可能会更正您的代码:
next(R1,R2) :-
select(R1, [red, green, blue, yellow], Cs),
member(R2, Cs).
color(R1,R2,R3,R4,R5,R6):-
% region adjacency relations
next(R1,R2),
next(R1,R3),
next(R1,R4),
next(R2,R4),
next(R2,R5),
next(R3,R4),
next(R3,R6),
next(R4,R5),
next(R4,R6).
这比使用 dif/2.
在推理计数上稍微更有效编辑还是更好,用iso_dif/2,或者'old style'版本
next(R1, R2) :- color(R1), color(R2), R1 \= R2.
当然,color/1 来自 mat 的回答