-1

prolog 中的 count/3 和 for/3 有什么区别?以及如何使用减量-1的 for 循环(如for(I,9,0,-1))?

  • 例如 :

    Dec=-2, Min_bound=0, Max_bound=9
    结果 => 9,7,5,3,1

4

2 回答 2

3

Prolog (ECLiPSe/SICStus) 中的 count/3 和 for/3 有什么区别?

不同之处在于“模式”,即Max参数是用作输入(+) 还是输出(-)。

  • (-I,+Min,+Max)的模板用于控制循环迭代的次数。在开始循环时必须知道Max的值,即它可以是一个数字

    ?- ( for(I,1,3) do writeln(I) ).
    1
    2
    3
    

    或者它可以是带有实例化变量的表达式

    ?- Next=4, ( for(I,1,Next-1) do writeln(I) ).
    1
    2
    3
    

    终止条件是I >= Max

  • 模板计数(-I,+From,-To)用于计算迭代次数。在开始循环时,To通常是一个未实例化的变量,在循环结束时,它与循环迭代的次数统一。在这样的设置中,迭代次数必须由其他东西控制,例如列表的长度,如下例所示:

    ?- ( foreach(X,[a,b,c]),count(I,1,N) do writeln(I-X) ).
    1 - a
    2 - b
    3 - c
    
    N = 3
    Yes (0.01s cpu)
    
  • 因为 Prolog 当然允许你使用一个值而不是一个未实例化的变量,所以你可以使用模板count(-I,+From,+To),但你应该知道终止条件是I=To,而不是I> =到

for/3count/3迭代器所属的do-loop构造试图为迭代递归的常见情况提供紧凑的表示法,并以一种让人想起过程循环表示法的方式这样做。逻辑变量的独特属性和 Prolog 的一般双向特性导致了一些有趣的特性,例如使用foreach/2迭代器,您可以使用相同的循环代码来遍历现有列表或构造新列表。在当前对数字进行迭代的情况下,遗憾的是没有实现这种对称性,因此您询问了两个不同的迭代器。

如何使用带有减量的for循环

没什么特别的,真的:

    ?- ( for(I,9,0,-2) do writeln(I) ).
    9
    7
    5
    3
    1
    Yes (0.00s cpu)

或者,为了在列表中收集结果:

    ?- ( for(I,9,0,-2),foreach(I,Is) do true ).
    Is = [9, 7, 5, 3, 1]
    Yes (0.00s cpu)

编辑:有人指出,上述内容在 SICStus (4.3.2) 中不起作用,因为不支持for/4迭代器。你仍然可以使用通用的fromto/4迭代器来做这样的循环,但你必须自己做一些算术,例如

?- ( fromto(9,I,I1,-1) do I1 is I-2, writeln(I) ).
9
7
5
3
1
Yes (0.01s cpu)

对于一般情况,这有点棘手,因此您实际上可以使用递归解决方案获得更清晰的代码......

于 2015-12-30T16:19:26.117 回答
2

首先,您的问题是关于 do-loops,这是在某些系统中发现的一种控制结构。SICStus 中的当前实现具有非常不稳定的行为 - 特别是 wrt count

| ?- for(I,5,1), foreach(I,List) do true.
List = [] ? ;
no
| ?- count(I,5,1), foreach(I,List) do true.
**LOOPS**

文档不清楚这个循环。但据我猜测,count将始终向上计数并期望该Max值是合法的;如果没有,它会循环。

在任何情况下,do-loops 中有太多这样的“功能”多年来仍未修复,您可能想先学习 Prolog 而没有 do-loops。特别是,考虑高阶结构,例如maplist/2..

于 2015-12-29T16:52:55.847 回答