Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

一个供Prolog爱好者学习与交流的地方


您没有登录。 请登录注册

模拟一般程序语言的do...while循环---dowhile谓词

浏览上一个主题 浏览下一个主题 向下  留言 [第1页/共1页]

dowhile(:Goal, :Condition)

模拟一般程序语言的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,
条件已不再成立就终止并回传。

查阅用户资料 http://prolog.longluntan.net

浏览上一个主题 浏览下一个主题 返回页首  留言 [第1页/共1页]

您在这个论坛的权限:
不能在这个论坛回复主题