Prolog术语连接

时间:2010-06-10 17:34:48

标签: prolog concatenation

我正在尝试从程序中格式化结果,但却很难。

我想给出这样的结果:

Res = do(paint(x) do(clean(a), do(repair(b) , initialState)))

基本上,我想将连续的术语连接到initialState原子但是,它不能用于atom_concat,因为连接的其他术语不是原子而且我想添加)每次我通过“do”函数

所以它会是这样的:Res = initialState。

当调用函数时,我会有一个像

这样的函数
concatenateTerm(Pred, Res, Res).

例如,预测修复(b)并获得结果:res = do(repair(b), initialState)。

这可以吗?

由于

3 个答案:

答案 0 :(得分:1)

如果我理解正确你需要做以下事情:

Res0 = initialState,
do(repair(b), Res0, Res1),
do(clean(a), Res1, Res2),
do(paint(x), Res2, Res3),

最终结果位于Res3。请记住,prolog过程不会“返回”任何内容,输入和输出值必须通过参数传递。

为什么要将连续的术语连接到 atom initialState?这不是序言。建立一个每次修改的结构在prolog中会更自然。

答案 1 :(得分:1)

我同意@rvirding的意见,你可能只需要构建一个PROLOG term 作为结果,而不是试图构建一个 atom 。即使你尝试后者(这确实是可能的),你通常可以使用效用函数(例如SWI-PROLOG中的atom_to_term/3term_to_atom/2)从原子转换为术语然后再转换回来,如果需要的话

无论如何,一个简单的谓词来获取你的“州”术语的整个列表并输出你之前描述的术语,如下所示:

build_do_term([X,Y], do(X,Y)) :- !.
build_do_term([X|Xs], do(X,Rem)) :-
    build_do_term(Xs, Rem).

根据州条款(其中必须至少有两个)调用此谓词:

?- build_do_term([paint(x), clean(a), repair(b), initialState], Rem).
Rem = do(paint(x), do(clean(a), do(repair(b), initialState))).

...反映了你所描述的追随的行为。如果您不想从列表中一次性构建术语,您仍然可以在自己的代码中使用上面do/2中使用的build_do_term/2术语构造方法来构造相应的{{1必要的术语。

答案 2 :(得分:-1)

@ d0pe,prolog中没有结果(它们存在于Mercury和Erlang中,我猜)只有在头部指定/统一的命名值,可能在后面的统一体中统一。在大多数情况下,执行Temp = Res, concatenateTerm (Pred,Temp, Res)会失败,因为Temp = Res, Res = do(Pred, Temp)将产生无限递归的术语do(Pred, do(Pred, do(Pred, ...)))(当适当的扩展可用时)。我猜这不是你想要的。
但现在我明白你想修改 Res - 这是对Prolog的错误理解。没有变量,您应该使用下一个方法Res0 = initialState, Res1 = do(repair(b), Res0), Res2 = do(clean(a), Res1), Res3 = do(paint(x), Res2).

可能你的规则看起来像(参见prolog中的猴子+ bananna的例子):

solve(FinalState, finish, FinalState). % our initial state is our goal

solve(InitState, do(Action, Future), FinalState):-
  action(InitState, Action, NewState),
  solve(NewState, Future, FinalState).