我正在尝试从程序中格式化结果,但却很难。
我想给出这样的结果:
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)。
这可以吗?
由于
答案 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/3
或term_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).