prolog 中的 count /3 和 for/3 有什么区别?

what is the difference between count /3 and for/3 in prolog?

序言中的 count/3 和 for/3 有什么区别? 以及如何使用 for-loop 递减 -1 like (for(I,9,0 ,-1))?

首先,您的问题是关于 do-loops,一种在某些系统中发现的控制结构。 SICStus 中的当前实现具有相当不稳定的行为 - 特别是 w.r.t。 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中有太多这样的"features"多年未修复,您可能想在没有do-loops的情况下学习Prolog。特别是,请考虑 higher-order 结构,例如 maplist/2..

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

区别在于"mode",即Max参数是否用作输入 (+) 或 输出 (-)。

  • 模板for(-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.

  • 模板count(-I,+From,-To)用于count迭代次数。在你开始循环时,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,不是我>=到.

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

如何使用 for-loop 和递减

没什么特别的,真的:

    ?- ( 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)

Edit:已经指出以上在SICStus(4.3.2)中不起作用,因为for/4 不支持迭代器。你仍然可以使用 general-purpose fromto/4 迭代器来做这样的循环,但是你必须自己做一些算术,例如

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

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