【问题标题】:Prolog: Make a list in recursion to a variableProlog:递归创建一个变量列表
【发布时间】:2016-05-11 09:29:40
【问题描述】:

我正在编写一条规则,即从一个节点到循环图中的目的地。为了做到这一点,我需要规则来记住访问过的节点,因为它在图表中移动。我的问题是我希望能够这样称呼它:

?- routeToDestination(startNode, destinationNode, Path)

并通过存储在 Path 变量中的图形获取路径。当我尝试在 Path 变量中附加节点时,我遇到了一些麻烦,因为它没有作为列表启动。到目前为止,我的规则如下所示:

routeToDestination(Destination, Destination, Path).
routeToDestination(Origin, Destination, Path):-
    link(Origin, Via),
    \+ visited(Via, Path),
    appendEnd(Path, Via, Result),
    routeToDestination(Via, Destination, Result).

这里的链接是一些事实,它们告诉哪里有来自 Via 的连接(即我检查我可以从 Via 去哪些节点),visited 检查元素是否已经在路径中(不想访问两次),appendEnd是典型的append函数(http://www.doc.gold.ac.uk/~mas02gw/prolog_tutorial/prologpages/lists.html):

append([],List,List).
append([Head|Tail],List2,[Head|Result]):-
    append(Tail,List2,Result).

每当我尝试进行调用时,append 函数似乎都失败了,因为 Path 是一个变量而不是一个列表。有没有解决方法,还是我想错了?

【问题讨论】:

  • 魔术:如果Via 是任何术语,那么[Via] 是具有单个元素的列表。但是使用append/3 通常表明您的方法存在问题。 prepend 元素,例如使用:Path = [Via|Path0]reverse 最后的路径,或者使用dcg 更有效地构建列表。
  • 谢谢,前置似乎容易多了!但是是否有可能最终将列表“返回”为 Path,以便我可以在规则之外使用它?
  • 当然:正如我所说,要么使用dcg 方便地描述列表,要么使用route_to_destination(Origin, Destination, Path0, Path) 的关系,其中Path0 用于反向构建路径 ,基本情况只是声明reverse(Path0, Path) 来反转它。
  • path/4

标签: recursion prolog


【解决方案1】:

Prolog 中一个非常常见的习惯用法是使用 helper 谓词,这些谓词带有 1 个或多个附加参数来为您维护状态。通常,这样的 helpers 将具有相同的名称但数量不同。

在该模式下,给定一个定义如下的有向图:

link(a,b).
link(a,c).
link(b,d).
link(d,a).

人们可能会这样遍历它:

connected( A , B , P ) :-
  setof(X,link(X,_),As) ,
  member(A,As) ,
  connected(A,B,[],P) ,
  .

connected( B , B , V , P ) :-
  reverse(V,P)
  .
connected( A , B , V , P ) :-
  link(A,X) ,
  \+ member(X,V) ,
  connected(X,B,[A|V],P)
  .

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 2015-05-12
    相关资源
    最近更新 更多