dowhile(:Goal, :Condition)
模拟一般程序语言的do...while循环。以C语言为例,此dowhile谓词可表述为
do{
____Goal;
}while(Condition);
Goal的编写有规定的格式:
前2个参数为保留参数,
规定第1个参数Static_Return为静态变量最终回传值,当静态变量多于一个时可用List表述;
规定第2个参数Static_Initial为静态变量初始值;
其后的"......"可自行增加传入或传出的变量,个数不限。
注意:
1. Static_Return与Static_Initial必须一一对应,也就是说如果为List形态,List内的元素个数须一样多。
2. 如果想传出的变量在Goal的多次选代过程中一旦被绑定后不会再需要被绑定为其他值,可用"......"自行增加变量传出(这种情形较少见);
但若被绑定后还有可能再被绑定为其他值,则必须用Static_Return传出(一般应该都是这种情况)。
如果想产生C语言里的break功能,则在Goal编写时,在想break的地方加入false。
这也意谓着…Goal一定是true的(false的话会被视为跳出循环),
如果确实想传出"false"信息而非break,可利用Static_Return增设一个变量传出。
使用break时还要特别注意:
一旦break,当次的迭代对静态变量的影响忽略不计,这点和一般语言的break不太一样。
例子可以参考for谓词的break用法。
例:
假设编写Goal谓词如下
211 ?- dowhile(add([C1, D1], [0, 0]), C1 =< 20).
C1 = 21,
D1 = 6.
add每选代一次就将D加1(变成D1),然后将D1加进C里,
也就是说C是从1开始累加到X,X取决于我们在dowhile中设的条件。
此例中我们设的是C1 =< 20,因此当累加到6时,C1变为21,
条件已不再成立就终止并回传。
模拟一般程序语言的do...while循环。以C语言为例,此dowhile谓词可表述为
do{
____Goal;
}while(Condition);
- 代码:
dowhile(Goal, Condition) :-
nonvar(Goal), nonvar(Condition), Goal =.. X, nth1(2, X, Ori), copy_term((Ori, Condition), (Return, CC)), replace(X, 2, Return, M), Z =.. M,
(Z -> (CC -> replace(X, 3, Return, W), V =.. W, dowhile(V, Condition); arg(1, Z, A), arg(1, Goal, A));
arg(2, Goal, A), arg(1, Goal, A)).
replace(List, Index, With, ListOut) :-
Idx is Index - 1, length(Before,Idx),
append(Before, [_Discard|Rest], List),
append(Before, [With|Rest], ListOut).
Goal的编写有规定的格式:
- 代码:
goal_name(Static_Return, Static_Initial, ......).
前2个参数为保留参数,
规定第1个参数Static_Return为静态变量最终回传值,当静态变量多于一个时可用List表述;
规定第2个参数Static_Initial为静态变量初始值;
其后的"......"可自行增加传入或传出的变量,个数不限。
注意:
1. Static_Return与Static_Initial必须一一对应,也就是说如果为List形态,List内的元素个数须一样多。
2. 如果想传出的变量在Goal的多次选代过程中一旦被绑定后不会再需要被绑定为其他值,可用"......"自行增加变量传出(这种情形较少见);
但若被绑定后还有可能再被绑定为其他值,则必须用Static_Return传出(一般应该都是这种情况)。
如果想产生C语言里的break功能,则在Goal编写时,在想break的地方加入false。
这也意谓着…Goal一定是true的(false的话会被视为跳出循环),
如果确实想传出"false"信息而非break,可利用Static_Return增设一个变量传出。
使用break时还要特别注意:
一旦break,当次的迭代对静态变量的影响忽略不计,这点和一般语言的break不太一样。
例子可以参考for谓词的break用法。
例:
假设编写Goal谓词如下
- 代码:
add([C1, D1], [C, D]) :- D1 is D + 1, C1 is C + D1.
211 ?- dowhile(add([C1, D1], [0, 0]), C1 =< 20).
C1 = 21,
D1 = 6.
add每选代一次就将D加1(变成D1),然后将D1加进C里,
也就是说C是从1开始累加到X,X取决于我们在dowhile中设的条件。
此例中我们设的是C1 =< 20,因此当累加到6时,C1变为21,
条件已不再成立就终止并回传。