Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地
Would you like to react to this message? Create an account in a few clicks or log in to continue.
Prolog 人工智能语言中文论坛---打造优质Prolog学习交流园地

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


您没有登录。 请登录注册

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

向下  留言 [第1页/共1页]

Mercury Liao


Admin

while(:Condition, :Goal)

模拟一般程序语言的while循环。以C语言为例,此while谓词可表述为

while(Condition){
____Goal;
};


代码:
while(Condition, Goal) :-
  nonvar(Condition), nonvar(Goal),
  Goal =.. X, nth1(2, X, Ori), copy_term((Condition, Ori), (CC, Return)),
  nth1(3, X, Ini), Ini = Return,
  (CC -> replace(X, 2, Return2, M), Z =.. M,
  (Z -> replace(X, 3, Return2, W), V =.. W, while(Condition, V); Ori = Ini);
  Ori = Ini).

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.


12 ?- while(C1 =< -1, add([C1, D1], [0, 0])).
C1 = D1, D1 = 0.

13 ?- dowhile(add([C1, D1], [0, 0]), C1 =< -1).
C1 = D1, D1 = 1.


C1 =< -1一开始就不成立,所以while/2一次都不执行(先检查,检查不通过则不执行),
但dowhile/2至少会执行一次(先执行,执行完后才检查是否再执行)。

注意到这里,虽然dowhile/2尚未开始执行add,
看起来C1应是个变量,无法判断C1 =< -1是否成立。
但实际操作中,一开始C1会被视为有初始值0(由add的第二个参数[0, 0]给出的),
所以是可以判断C1 =< -1是否成立的。

http://prolog.longluntan.net

返回页首  留言 [第1页/共1页]

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