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
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
不同之处在于“模式”,即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/3和count/3迭代器所属的do-loop构造试图为迭代递归的常见情况提供紧凑的表示法,并以一种让人想起过程循环表示法的方式这样做。逻辑变量的独特属性和 Prolog 的一般双向特性导致了一些有趣的特性,例如使用foreach/2迭代器,您可以使用相同的循环代码来遍历现有列表或构造新列表。在当前对数字进行迭代的情况下,遗憾的是没有实现这种对称性,因此您询问了两个不同的迭代器。
没什么特别的,真的:
?- ( 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)
对于一般情况,这有点棘手,因此您实际上可以使用递归解决方案获得更清晰的代码......
首先,您的问题是关于 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..
。