prolog - Prolog中属性变量的删除

标签 prolog

我正在从事一个涉及图形的项目,我有一个属性变量列表,每个属性变量代表图形中的一个节点。每个节点都有几个属性,例如相邻节点、到起始节点的距离等。我想从列表中删除单个节点,但是当我使用 delete 时,出现以下错误:

ERROR: uhook/3: Undefined procedure: adjs:attr_unify_hook/2

例如,如果我在我的程序中包含 delete(OldVertices, Node, NewVertices),我会收到此错误。

如果我将我的顶点存储在二进制堆中,并尝试使用 delete_from_heap 从堆中删除一个顶点,我也会得到完全相同的错误。

如果我首先删除它的所有属性,我能够在节点上成功地使用 delete 和 delete_from_heap,但这会给我的程序带来问题,因为我想稍后使用这些属性;我只是不希望节点包含在列表或二进制堆中。

这是一个错误,还是我对属性变量的处理不正确?

编辑:

谢谢!这适用于列表。现在我正在尝试做一些类似的事情来从二进制堆中删除属性变量。我有一个规则

delheap(Heap, Key, NewHeap) :-  
    delete_from_heap(Heap, A1, A0, NewHeap),
    get_attr(Key, dist, A1),
    A0 == Key.

然而,当我进行测试时,我得到以下结果:

?- TLO = [3-A, 4-B], put_attr(A, dist, 3), put_attr(B, dist, 4), list_to_heap(TLO, H), delheap(H, A, Hq).
Correct to: "dijkstra_av:delheap(H,A,Hq)"? yes
TLO = [3-A, 4-B],  H = heap(t(A, 3, [t(B, 4, [])]), 2),  Hq = heap(t(B, 4, []), 1),  put_attr(A, dist, 3),  put_attr(B, dist, 4).

效果很好,但是当我尝试使用 B 时:

?- TLO = [3-A, 4-B], put_attr(A, dist, 3), put_attr(B, dist, 4), list_to_heap(TLO, H), delheap(H, B, Hq).
Correct to: "dijkstra_av:delheap(H,A,Hq)"? yes
TLO = [3-A, 4-B], false.

编辑 2:

我能够通过使用优先级而不是键调用 delete_from_heap 来使其工作,但是,如果两个项目具有相同的优先级并且它选择了错误的项目,这确实会导致问题。在我的应用程序中,这个问题并不经常出现,但似乎通常应该有更好的方法来使用现有规则的属性变量。

最佳答案

您不小心统一了一个变量,该变量的属性附加了另一个术语。涉及属性变量的统一会触发相应模块中的 attr_unify_hook/2 ,并且您没有定义此类 Hook ,因为您仅将属性用作访问数据的快速方式,并且可能对之间的任何统一不感兴趣这些变量。

要从列表中删除变量,请使用例如 (==)/2:

list0_var_list(Ls0, V, Ls) :-
        select(V0, Ls0, Ls),
        V0 == V.

示例查询:

?- list0_var_list([A,B,C,D], B, Ls).
Ls = [A, C, D] ;
false.

请注意,这仍然留下一个选择点。您可以使用 once/1 提交第一个也是唯一的解决方案,因为您已经知道列表中的每个节点都是唯一的:

?- once(list0_var_list([A,B,C,D], B, Ls)).
Ls = [A, C, D].

使用这样的谓词而不是 delete/3 可以让您安全地检测变量的相等性并从列表中删除给定的变量,而不会触发任何统一 Hook 。

另请注意 delete/3 已被弃用(请参阅文档),并考虑以下情况:

?- delete([A,B,C], A, Cs).
Cs = [].

这表明当涉及变量时,您不能安全地使用 delete/3

关于prolog - Prolog中属性变量的删除,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32386030/

相关文章:

prolog - prolog 中的二叉树计数节点

list - 列表谓词的长度如何工作

prolog - 以声明方式解决汉诺塔(Prolog)

prolog - 在序言中查找两个列表之间不重复的交集

prolog - 在 Prolog 中停止递归?

Prolog 中的谓词列表

shell - 如何通过 shell 调用在 SWI-Prolog 中显示模式匹配目标的结果?

prolog - NP完整背包

prolog - 约束逻辑程序中的异常警告和计算结果

prolog - 序言中的国际象棋游戏