常常在写prolog的时候,会需要用到循环,
prolog里没有for语法还是挺不方便的,
每次重复做一件事就得用递归来写(或者是我功力不够?),
所以我试着想把prolog的循环标准化,
目前写的for谓词如下:
当你想执行下面这段代码执行10遍时(意即从1印到10):
你只要查询
就可得到你想要的结果。
这固然可以满足我们的部分需求。
但有时这样不能满足我们的要求,我们可能想求List的和,比如[1,2,3,4,5]加总(假设不能用sumlist谓词),
得到1+2+3+4+5=15,
这时候如果仿照C++或VBA,你可以用一个容器变量C,
C一开始等于0,然后I = 1, C = C + I, I = 2, C = C + I……
最后C就会等于15。
但这里无法,因为对每个wri谓词来说,C都是独立的,
我还没找到一个可以不用assert与retract的方法可以达到完美的for,
有没方法可以弥补这个缺陷,让查询如for(wri(I, C), 1, 10)时,C能够"记得"每次加总后的结果?
prolog里没有for语法还是挺不方便的,
每次重复做一件事就得用递归来写(或者是我功力不够?),
所以我试着想把prolog的循环标准化,
目前写的for谓词如下:
- 代码:
for(Predicate, Index_From, Index_To) :- for(Predicate, Index_From, Index_To, 1).
for(Predicate, Index_From, Index_To, Index_Step) :-
nonvar(Predicate),
(Index_From =< Index_To -> Predicate =.. X, replace(X, 2, Index_From, Y), Z =.. Y, Z,
Next_Index is Index_From + Index_Step, for(Z, Next_Index, Index_To, Index_Step); true).
replace(List, Index, With, ListOut) :-
Idx is Index - 1, length(Before,Idx),
append(Before, [_Discard|Rest], List),
append(Before, [With|Rest], ListOut).
当你想执行下面这段代码执行10遍时(意即从1印到10):
- 代码:
wri(I) :- write(I), nl.
你只要查询
- 代码:
?- for(wri(I), 1, 10). % 意即C++语法:for(i=1;i<=10;i++){wri(i);} 或VBA语法:For i = 1 to 10: wri(i): Next
就可得到你想要的结果。
这固然可以满足我们的部分需求。
但有时这样不能满足我们的要求,我们可能想求List的和,比如[1,2,3,4,5]加总(假设不能用sumlist谓词),
得到1+2+3+4+5=15,
这时候如果仿照C++或VBA,你可以用一个容器变量C,
C一开始等于0,然后I = 1, C = C + I, I = 2, C = C + I……
最后C就会等于15。
但这里无法,因为对每个wri谓词来说,C都是独立的,
我还没找到一个可以不用assert与retract的方法可以达到完美的for,
有没方法可以弥补这个缺陷,让查询如for(wri(I, C), 1, 10)时,C能够"记得"每次加总后的结果?