当is_adjacent([X1,Y1], [X2,Y2])
是[X2,Y2]
的邻居时,我有一个[X1,Y1]
条款。如果我问is_adjacent([2,2], [X,Y])
,我会得到所有可能的结果(四个),在这种情况下:
is_adjacent([2,2],[X,Y]).
X = 2,
Y = 3 ;
X = 3,
Y = 2 ;
X = 2,
Y = 1 ;
X = 1,
Y = 2.
我想在另一个子句中使用此行为:
anotherClause :-
is_adjacent([2,2],[X,Y]),
[to be continued...].
现在,我如何自动处理每一个可能的结果?例如,如果我想检查每个结果是否是特定列表的成员。
感谢您的回答!
答案 0 :(得分:1)
有forall / 2,似乎符合您的要求:
% this fails because not all results are in list
anotherClause :-
forall(is_adjacent([2, 2], [X, Y]),
memberchk([X, Y], [[2, 3], [3, 2]])).
% this succeed, all results are in list
anotherClause :-
forall(is_adjacent([2, 2], [X, Y]),
memberchk([X, Y], [[2, 3], [3, 2], [1, 2], [2, 1]])).
出于测试目的,我用这种方式编码is_adjacent:
is_adjacent([A, B], [X, Y]) :-
member(U / V, [1 / 0, 0 / 1, -1 / 0, 0 / -1]),
X is A + U, Y is B + V.
答案 1 :(得分:0)
要针对其他规则检查is_adjacent
的每个结果,您需要做的就是用X
和Y
来编写该规则,如下所示:
anotherClause :-
is_adjacent([2,2],[X,Y]),
X > 0,
Y > 0,
check_x_and_y(X, Y, Result),
...
等等。在评估anotherClause
时,Prolog会将X
和Y
与第一组值统一起来,然后继续使用该子句的其余部分(上面,它会检查X
}和Y
大于零,并使用check_x_and_y
规则评估两个变量。一旦规则出现一组分配,它就会将它们提供给您,并让您停止或继续。如果您希望一直持续到整个集合耗尽(例如,打印X
和Y
的所有作业),则模式如下所示:
anotherClause :-
is_adjacent([2,2],[X,Y]),
print_x_and_y(X,Y),
fail.
anotherClause.
第一条规则遍历X
,Y
的每个分配,打印它们,然后无法触发重新评估。第二条规则是阻止进一步评估的全面事实。
这是一个打印所有相邻单元格的link to a demo on ideone。
答案 2 :(得分:0)
如果您想收集所有解决方案,我认为您可能正在寻找谓词集setof
。这可以找到谓词的所有解法。
setof([X,Y], is_ajacent([2,2],[X,Y], Z)
然后
Z = [[2,3], [1,2], ...]
如果您不想收集所有解决方案,只是为每个解决方案执行某些操作,那么请执行dasblinkenlight第二个解决方案。特别是fail
最后,所以Prolog尝试下一个解决方案。然后终于成功了。
答案 3 :(得分:0)
有一种方法可以将∀(为所有)转换为there(存在),而不是双重方法:
∀x.f(x)=¬¬∀x.f(x)=¬∃x.¬f(x)
anotherClause :- \+(notAnotherClause).
notAnotherClause :- is_adjacent([2,2],[X,Y]), \+(memberchk([X,Y], SomeList)).
想法是我们在所有替代方案中寻找负面结果的存在,而缺少这种方法实际上意味着“适用于所有变体”。
P.S。 \+/1
\+(Goal)
)有时写成not/1
(not(Goal)
)