在prolog中处理所有可能的结果

时间:2013-04-18 14:18:22

标签: prolog

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...].

现在,我如何自动处理每一个可能的结果?例如,如果我想检查每个结果是否是特定列表的成员。

感谢您的回答!

4 个答案:

答案 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的每个结果,您需要做的就是用XY来编写该规则,如下所示:

anotherClause :-
    is_adjacent([2,2],[X,Y]),
    X > 0,
    Y > 0,
    check_x_and_y(X, Y, Result),
    ...

等等。在评估anotherClause时,Prolog会将XY与第一组值统一起来,然后继续使用该子句的其余部分(上面,它会检查X }和Y大于零,并使用check_x_and_y规则评估两个变量。一旦规则出现一组分配,它就会将它们提供给您,并让您停止或继续。如果您希望一直持续到整个集合耗尽(例如,打印XY的所有作业),则模式如下所示:

anotherClause :-
    is_adjacent([2,2],[X,Y]),
    print_x_and_y(X,Y),
    fail.

anotherClause.

第一条规则遍历XY的每个分配,打印它们,然后无法触发重新评估。第二条规则是阻止进一步评估的全面事实。

这是一个打印所有相邻单元格的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/1not(Goal)