代码之家  ›  专栏  ›  技术社区  ›  devoured elysium

“返回”prolog中谓词的列表

  •  3
  • devoured elysium  · 技术社区  · 14 年前
    resolve(K, K, _) :- writeln('finished'). %goal state
    
    resolve(CurrentState, GoalState, Path) :-
        suc(_, CurrentState, NextState, GoalState),
        append(Path, [CurrentState], NextPath),
        resolve(NextState, GoalState, NewPath).
    

    我现在有这个算法,它可以正常工作。我是这样运行的:

    resolve(0, 10, Path).
    

    我确信算法是按它应该的方式运行的,但是它会到达目标状态。 Path 的价值是

    Path = []
    

    这不是应该发生的。路径应该包含我的算法通过的“状态”序列。 可能有什么问题?

    3 回复  |  直到 13 年前
        1
  •  5
  •   mat    14 年前

    最简单的方法是使用DCG表示法来描述列表:

    path(State0, Target) -->
        (    { State0 == Target } -> []
        ;    { suc(_, State0, State1, Target) },
             [State1],
             path(State1, Target)
        ).
    

    您也可以手动执行此操作:

    path(State0, Target, Path) :-
        (    State0 == Target -> Path = []
        ;    suc(_, State0, State1, Target),
             Path = [State1|Rest],
             path(State1, Target, Rest)
        ).
    

    这里不需要累加器来获得线性时间。

        2
  •  1
  •   gusbro    14 年前

    我相信在你想要建立道路的方式上有一个问题。 您可能想要重写它,以便在谓词的头部构建它。 像这样:

    resolve(K, K, []) :- writeln('finished'). %goal state
    resolve(CurrentState, GoalState, [CurrentState|Path]) :-
        suc(_, CurrentState, NextState, GoalState),
        resolve(NextState, GoalState, Path).
    

    第一个子句结束递归:若要从状态k转到状态k,则返回[]作为路径,因为您已经处于目标状态。 第二个子句构建路径,它获取下一个状态并以递归方式调用resolve,构建递归结束时所遍历的路径。

        3
  •  0
  •   Enigmativity    14 年前

    应该这个词 NextPath 在你 append 谓语be NewPath ?

    目前没有任何其他用法 下一路径 所以 Path 必须绑定到 [] 因为 下一路径 能够完全绑定到 [CurrentState] .

    推荐文章