Farmer的谜题 - 递归规则和累加器打破了我的方法

时间:2015-07-11 23:49:04

标签: prolog river-crossing-puzzle

几个小时前我开始学习Prolog,而且我很难尝试为农民问题实施解决方案。我知道网络中有很多例子,但为了学习的目的,我想了解为什么我的代码不起作用,方法是否有效,以及 what&#39 ; s推理像这样的问题的正确方法

见下面的代码。我所做的是:

  • 定义指示状态是否有效的规则(安全,来自 农民的观点:))
  • 定义指示转换是否有效且安全的规则
  • 定义代表有效旅程的规则

到目前为止我所取得的成就是:

  1. 如果我通过提供潜在解决方案测试 行程规则,行为正确
  2. 如果我提问 旅行规则,只找到解决方案,如果我将问题缩短为三个步骤,例如旅行(州(s,s,s,s),州(s,n,s,s),R)
  3. 我认为我发现了问题,如果我错了,请纠正我:如果解决方案需要3个以上的步骤,则最后行程规则评估至少两次,并且在第一次递归执行后, PreviousStates 累加器不为空。当统一?已探索的答案时, not(member(Next,PreviousStates)) 会失败,因为 Next state包含的变量将匹配 PreviousStates 列表中已有的内容。

    所以,我的问题是:

    1. 我的结论是否正确?如果没有,那真正的问题是什么?
    2. 如果我在前一点是对的,我该如何解决这个问题?也许我错了,但我采取的方法对我来说似乎很合乎逻辑。我在哪里失败了?我是否必须彻底改变问题的方法?
    3. 提前感谢您的帮助!

      %Define what are the unsafe states for the Farmer, Goat, Cabbage and Wolf
      unsafeState(F,G,C,W) :-
          (C=G, not(C=F));
          (G=W, not(G=F)).
      safeState(F,G,C,W) :- not(unsafeState(F,G,C,W)).
      
      %Define what are the valid and safe transitions
      isSafeTransition(state(F,F,C,W),state(Fend,Fend,C,W)) :- safeState(F,F,C,W), safeState(Fend,Fend,C,W).
      isSafeTransition(state(F,G,F,W),state(Fend,G,Fend,W)) :- safeState(F,G,F,W), safeState(Fend,G,Fend,W).
      isSafeTransition(state(F,G,C,F),state(Fend,G,C,Fend)) :- safeState(F,G,C,F), safeState(Fend,G,C,Fend).
      isSafeTransition(state(F,G,C,W),state(Fend,G,C,W))    :- safeState(F,G,C,W), safeState(Fend,G,C,W).
      
      % Initial matching rule
      trip(A,B,Path):- trip(A,B,Path, []).
      
      % Finishing rule
      trip(CurrentState, EndState,Path, _):-
          [CurrentState| [EndState|[]] ] = Path,
          isSafeTransition(CurrentState, EndState).
      
      trip(CurrentState,EndState,Path, PreviousStates):-
          [CurrentState|[Next|Tail]] = Path,
          not(member(Next,PreviousStates)),
          isSafeTransition(CurrentState,Next),
          trip(Next,EndState, [Next|Tail], [CurrentState|PreviousStates]).
      

1 个答案:

答案 0 :(得分:0)

我自己发现了这个问题,我发布了解释,以防有人帮忙。

问题在于没有任何限制职位可能值的规则。基本上我忘记将可能的值限制为 n s ......

解决查询时,变量的潜在值是无限的。这就是为什么包含变量的状态存储在累加器中并与下一个状态匹配的原因。

为了解决这个问题,我已经添加了两个事实来定义有效的职位值,并修改了控制状态是否有效的规则或不包括这些价值观。

在下面找到固定程序:

% Define the valid sides for any participant    
side(n).
side(s).

% Define what are the valid states for the Farmer, Goat, Cabbage and Wolf
unsafeState(F,G,C,W) :-
    (C=G, not(C=F));
    (G=W, not(G=F)).
validState(F,G,C,W) :-
    side(F),side(G),side(C),side(W),
    not(unsafeState(F,G,C,W)).

%Define what are the valid and safe transitions
isSafeTransition(state(F,F,C,W),state(Fend,Fend,C,W)) :- 
    validState(F,F,C,W), validState(Fend,Fend,C,W).
isSafeTransition(state(F,G,F,W),state(Fend,G,Fend,W)) :- 
    validState(F,G,F,W), validState(Fend,G,Fend,W).
isSafeTransition(state(F,G,C,F),state(Fend,G,C,Fend)) :- 
    validState(F,G,C,F), validState(Fend,G,C,Fend).
isSafeTransition(state(F,G,C,W),state(Fend,G,C,W))    :- 
    validState(F,G,C,W), validState(Fend,G,C,W).

% Initial matching rule
trip(A,B,Path):- trip(A,B,Path, []).

% Finishing rule
trip(CurrentState, EndState,Path, _):-
    [CurrentState| [EndState|[]] ] = Path,
    isSafeTransition(CurrentState, EndState).

trip(CurrentState,EndState,Path, PreviousStates):-
    [CurrentState|[Next|Tail]] = Path,
    not(member(CurrentState,PreviousStates)),
    isSafeTransition(CurrentState,Next),
    trip(Next,EndState, [Next|Tail], [CurrentState|PreviousStates]).

我仍然是Prolog的新手,所以如果有人可以做任何更正,请做!