在不使用非声明性if-then-else语法的情况下在Prolog中进行适当的流控制

时间:2016-03-19 03:19:38

标签: if-statement prolog flow-control logical-purity

我想检查一个任意事实,如果它在知识库中,则执行某些操作,如果不是,则执行其他操作,但不使用( I -> T ; E)语法。

我的知识库中有一些事实:

unexplored(1,1).
unexplored(2,1).
safe(1,1).

给出不完整的规则

foo:- safe(A,B),
% do something if unexplored(A,B) is in the knowledge base
% do something else if unexplored(A,B) is not in the knowledge base

处理这个问题的正确方法是什么,不这样做?

foo:-
   safe(A,B),
   ( unexplored(A,B) -> something ; something_else ).

2 个答案:

答案 0 :(得分:2)

不是答案,但评论时间太长。

"流量控制"根据定义,不是声明性的。在运行时更改谓词数据库(定义的规则和事实)也不是声明性的:它会向您的程序引入状态。

你应该非常仔细地考虑你的数据"属于数据库,或者如果您可以保留数据结构。但是你的问题并没有提供足够的细节来提出任何建议。

但您可以看到this example of finding paths through a maze。在此解决方案中,数据库包含有关不会更改的问题的信息。搜索本身使用最简单的数据结构,即列表。 "流量控制"如果你想调用它,这是隐含的:它只是Prolog寻找证据的副作用。更重要的是,你可以在不考虑确切的控制流程的情况下争论该程序及其功能(但你确实考虑了Prolog的解决策略)。

答案 1 :(得分:1)

此要求的根本问题在于非单调

  

添加这样的事实后,持有这个事实的事情可能会突然失败

这本质上与单调性的重要和理想的陈述性特征背道而驰。

声明地说,通过添加事实,我们希望最多获得增加,而不是减少持有的东西。

出于这个原因,您的要求本质上与非单调结构相关联,例如if-then-else,!/0setof/3

推理这种方法的理由是完全避免检查知识库的属性。相反,要专注于对持有的事物的清晰描述,使用Prolog子句对知识进行编码。

在您的情况下,您似乎需要推断某些搜索问题的状态。解决此类任务的一种声明方式是将州表示为Prolog术语,并编写涉及国家的纯粹单调规则。

例如,如果我们探索之前未探索过的某个位置S0,请说明州S与州Pos相关:

state0_state(S0, S) :-
    select(Pos-unexplored, S0, S1),
    S = [Pos-explored|S1].

或更短:

state0_state(S0, [Pos-explored|S1) :-
    select(Pos-unexplored, S0, S1).

我留下了我在这里使用的状态表示作为一个简单的练习。请注意使用S0S1,...,S链接不同状态的方便命名约定。

这样,您可以编码关于代表状态的Prolog术语的显式关系。纯粹,单调,并在各个方向工作。