Prolog 规划器仅生成一个计划

我有一个 Prolog 规划器,它的工作正常,但有一个主要问题是每次只能生成一个计划。虽然计划是正确的,但我的应用确实需要所有可能的计划。

plan(State, Goal, _, Moves) :-  subsetB(Goal,State),                            write('moves are'), nl,                            reverse_print_stack(Moves).plan(State, Goal, Been_list, Moves) :-                            effects(Name, [Preconditions, Add,Delete]),  //a list of of rules governing the domain                            conditions_met(Preconditions, State),       //checks if all preconditions are present in the state                            change_state(State, Add,Delete, Child_state), //add predicates from Add list, removes predicates in the Delete list and stores result in Child_state                            \+(member_state(Child_state, Been_list)),     //checks if Child_state hasn't been previously visited                            stack(Child_state, Been_list, New_been_list),                            stack(Name, Moves, New_moves),                    plan(Child_state, Goal, New_been_list, New_moves).change_state(S, [],[], S).change_state(S, [], Delete, S_new) :-   change_state(S, [],[], S2),                                    apply_del(Delete, S2, S_new).change_state(S, Add,Delete, S_new) :-   change_state(S, [], Delete, S2),                                    apply_add(Add, S2, S_new).apply_add([],State,State).apply_add([activate(App)|Rest],State,InterimState) :-apply_add(Rest,State,S2),find_stones(App,State,StonesToBeActivated), make_active(StonesToBeActivated,S2, InterimState).apply_add([First|Rest],State,InterimState) :- apply_add(Rest,State,S2),add_element(First, S2, InterimState).apply_del([],InterimState,InterimState).apply_del([First|Rest],InterimState,NewState) :- apply_del(Rest, InterimState,S2),del_element(First, S2, NewState).subsetB([],_).subsetB([F|R],S) :- member(F,S),subsetB(R,S).%dropping a stone inside app1  effects(drop(X,app1),                     %action   [[stone(X),active(X)],                  %preconditions    [in(app1,X)],                          %postconditions : add list    [active(X)]]).                         %postconditions : delete listgo(S,G,AllPlans):- findall(Moves, plan(S,G,[S],Moves),AllMoves).conditions_met(P, S) :- subsetB(P, S).

示例调用 go([in(app1,s1), stone(s2), active(s2),stone(s3),active(s3)],[in(app1,s1),in(app1,s3),in(app1,s2)],AllPlans).

回答:

drop(s2,app1)drop(s3,app1) //correct_2368_2366_2364_2362_2360_2358_2356_2354_2352_2350_2348_2346_2344_2342_2340_2338_2336等… 无限


回答:

要查找目标的所有解决方案,请查看bagof 或 findall。还是我遗漏了什么?

像这样:

?- findall(Moves, plan(State, Goal, _, Moves), AllMoves).

这些谓词的整个理念是,你指定要收集哪些参数,并得到该谓词下所有可能的实例化列表。从这个意义上讲,你通常有一个“返回”值(一个与结果一起实例化的参数),然后你可以查看或打印它,而不是在查找解决方案的谓词中显式地打印它。

一个简单的例子:

foo(1). foo(2). foo(3). foo(4). foo(5). foo(6).bar(R) :- foo(A), A mod 2 =:= 0.findall(R, bar(R), Even).

现在谈谈递归:它是如何工作的?你不能在同一个谓词的不同子句之间共享变量。例如,这是不正确的:

baz(0, B).baz(X, B) :- X0 is X - 1, B1 is B + 1, baz(X0, B1).

因为在 baz 的第一个子句中 B 是一个单例变量。相反,你可以这样做:

baz(0, B, B).baz(X, B, Result) :- X0 is X - 1, B1 is B + 1, baz(X0, B1, Result).

现在你可以这样调用:

?- baz(10, 2, Result).Result = 12

但在第一个答案之后你仍然会遇到问题。

你得到单个正确的计划可能是因为 plan 的第一个子句不满足 subsetB 的要求,你进入了第二个子句。在那里,你创建了一个 Moves,它的尾部有一个自由变量,但这还不是问题。然而,问题是,当你找到你的第一个解决方案(都在第二个 plan 子句中,递归地),Moves 现在被绑定到一个动作列表,而不是开始寻找新的解决方案,你通过回溯再次进入第二个子句,带有已经填充的 Moves,这可能会搞乱算法的其余部分。

为了使其正确,你可能需要确保当你的 plan 回溯时,它开始寻找新的解决方案,并使用一个干净的 Moves。你可以从将 Moves 实例化为一个空列表并在累加器中收集结果开始,如上面的简单 baz 谓词所示。

Related Posts

Keras Dense层输入未被展平

这是我的测试代码: from keras import…

无法将分类变量输入随机森林

我有10个分类变量和3个数值变量。我在分割后直接将它们…

如何在Keras中对每个输出应用Sigmoid函数?

这是我代码的一部分。 model = Sequenti…

如何选择类概率的最佳阈值?

我的神经网络输出是一个用于多标签分类的预测类概率表: …

在Keras中使用深度学习得到不同的结果

我按照一个教程使用Keras中的深度神经网络进行文本分…

‘MatMul’操作的输入’b’类型为float32,与参数’a’的类型float64不匹配

我写了一个简单的TensorFlow代码,但不断遇到T…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注