【问题标题】:freeze for more than one variable冻结多个变量
【发布时间】:2015-06-08 12:19:57
【问题描述】:

我尝试编写一个谓词,它接受一个列表并将其转换为平衡树。我的代码如下所示:

/* make_tree(list, tree)
 *
 *    list: list with the elements of the tree in prefix order
 *    tree: balanced tree of the elements in the list
 * 
 */
make_tree([], empty).
make_tree([H|T], node(L, R, H)):-
    split_half(T, T1, T2),
    make_tree(T1, L),
    make_tree(T2, R).

/* split_half(list, first, second)
 * 
 *    list: list with n elements
 *    first: list with first (n // 2) elements
 *    second: list with last (n - n // 2) elements
 *
 */
split_half(L, L1, L2):-
   split_half(L, L, L1, L2).

split_half(L, [], [], L):- !.
split_half(L, [_], [], L):- !.
split_half([H|T], [_,_|Acc], [H|L1], L2):-
   split_half(T, Acc, L1, L2).

这在调用时有效:

?- make_tree([1,2,3], Tree).
Tree = node(node(empty, empty, 2), node(empty, empty, 3), 1).

但是以其他方式调用它时不起作用,例如:

?- make_tree(L, node(node(empty, empty, 2), node(empty, empty, 3), 1)).
false.

这并不是真的必要,但我还是接受了挑战,让它双向发挥作用。我想通过在split 上使用freeze/2 来解决这个问题,比如freeze(T2, split(T, T1, T2)),这使得?- make_tree(L, node(node(empty, empty, 2), node(empty, empty, 3), 1)). 有效,但原来的想法不再适用。所以实际上我正在寻找的是某种freeze/2,它可以做类似freeze((T;T2), split(T, T1, T2)) 的事情。有人知道如何解决这个问题吗?

提前致谢

【问题讨论】:

  • 不要对此类谓词使用切割。
  • 您的代码不正确:make_tree(T2, L). 应为 make_tree(T2, R).
  • @false 我更正了。剪裁有什么问题?主要是为了让代码具有确定性……

标签: prolog prolog-coroutining


【解决方案1】:

您很可能正在寻找when/2。它由 SICStus Prolog (manual page) 和 SWI-Prolog (manual page) 提供。

使用示例:

myfreeze1(V,Goal) :-
   when(nonvar(V),Goal).

myfreeze2(V1,V2,Goal) :-
   when((nonvar(V1);nonvar(V2)),Goal).

【讨论】:

  • 你为什么使用nonvar而不是ground
  • @MrTsjolder。我以为你想要类似于 freeze/2 的东西,它会延迟到 nonvar,而不是接地。见sicstus.sics.se/sicstus/docs/latest4/html/sicstus.html/…
  • 我只看了swi-prolog,恐怕我不确定我是否足够了解nonvarground之间的区别...无论如何谢谢!
  • @MrTsjolder。如果V 不是变量(而是整数、浮点数、原子或化合物等),则nonvar(V) 成功。 ground(V) 还要求 V 不包含任何变量。不同之处体现在复合词上。
  • 例如,术语t(V) 是非var,但也不是ground。
【解决方案2】:

这是一种不使用协同程序的方法。这个想法是首先在树和它的元素的 number 之间建立一个关系,它由一个列表表示。请注意,我们首先不查看具体元素 (_),因为我们还不知道它们的顺序。元素数量固定后,我们可以像以前一样继续进行,但没有削减。

list_tree(Xs, Tree) :-
   phrase(tree_els(Tree), Xs),
   make_tree(Xs, Tree).

tree_els(empty) -->
   [].
tree_els(node(L, R, _)) -->
   [_],
   tree_els(L),
   tree_els(R).

出于性能原因,此版本可能会从协同程序中受益。毕竟tree_els/1 对所有可能的树都会成功,无论它们是否平衡。

【讨论】:

  • --> 语法和phrase 是什么?很抱歉问了这个问题,但我没有学到这些东西。
  • 定句语法,dcg。可在任何 Prolog 中使用
  • @MrTsjolder。谢谢你问-->phrase是什么意思
猜你喜欢
  • 2015-01-07
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多