【问题标题】:increment and backtracking in prologprolog中的增量和回溯
【发布时间】:2018-04-20 01:39:51
【问题描述】:

我的目的是统计 Prolog 中两个节点之间的节点数。例如,在本例中,node1 和 node3 之间有一个节点(node2):

link(node1,node2).
link(node2,node3).

因为我们无法更改已经在 Prolog 中实例化的变量的状态,所以我的第一个直觉是尝试使用类似这样的递归来计数:

nb_nodes_netween(N1,N2,R) :-
    link(N1,N2).
nb_nodes_netween(N1,N2,R) :-
    link(N1,A),
    T is R+1,
    nb_nodes_netween(A,N2,T).

我的问题与柜台有关.. 谢谢你

编辑 新版本以 R 变量作为 OUT 值(最终结果)和 T 变量作为 IN 值(一种累加器)。

R = R + 1 但我不知道如何在 Prolog 中翻译它。也许我可以将节点存储在列表中,T 是列表的长度。

nb_nodes_between(N1,N2,R) :-
    link(N1,N2).
nb_nodes_between(N1,N2,R) :-
    link(N1,A),
    R is T+1,% TODO 
    nb_nodes_netween(A,N2,R).

【问题讨论】:

  • 您需要一个“输入”值和一个“输出”值。
  • 我觉得应该是nb_nodes_netween(N1,N2,0):-link(N1,N2)。
  • 嗯,我真的不明白为什么。我认为我的问题更多是翻译这一步:Result = Result +1
  • R = R + 1 在您想为R 插入一个具体原子时永远不会为真,R is R + 1 也是如此(2 永远不会与 3 相同,等等)。您需要一个新变量 S = R +1 并将 S 作为附加参数传递给您的谓词。
  • 解决这种情况的一种可能方法是通过setof/3 枚举从 A 到 B 的所有可能路径并计算结果的长度。这仅在路径数量有限的情况下才有效,因此您需要处理图中的循环。 (并且您需要先描述 A 和 B 之间的路径)。

标签: prolog increment backtracking


【解决方案1】:

所以,解决方法很简单:

nb_nodes_between(N1,N2,R,R) :-
    link(N1,N2).
nb_nodes_between(N1,N2,T,O) :-
    link(N1,A),
    R is T+1,% TODO 
    nb_nodes_between(A,N2,R,O).

?- nb_nodes_between(node1,node3,0,O).
O = 1
false

我想指出一点:假设你有这个知识库来表示图形:

link(node1,node2).
link(node2,node3).
link(node3,node4).
link(node4,node2).

尝试查询:

?- b_nodes_between(node1,node2,0,O).
O = 0
O = 3
O = 6
O = 9
O = 12
O = 15
and so on...

有了这个解决方案,如果图形中有循环,程序也会循环。为避免循环并仅获得一条路径,您必须在代码中添加一个剪切 !,如下所示:

nb_nodes_between(N1,N2,R,R) :-
    link(N1,N2),!. %<-- note the cut !

?- nb_nodes_between(node1,node2,0,O).
O = 0

【讨论】:

  • 谢谢,但我最多只需要 3 个参数,然后我需要找到一个解决方案来初始化 T。
  • 只需在nb_nodes_between_aux/4 中重命名nb_nodes_between/4,然后创建一个nb_nodes_between/3 谓词即可:nb_nodes_between(N1,N2,T):- nb_nodes_between_aux(N1,N2,0,T). 完成
  • 事实上我的限制是我只能创建这个谓词nb_nodes_between/3 那么我的方法可能无法解决这个问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多