关于在Prolog中读取和格式化输入文本的程序中使用剪切的一些疑问

时间:2013-04-17 11:46:09

标签: prolog

我对这个简单的Prolog示例的声明性解释有一些疑问,该示例从当前输入流中读取一个句子并输出重新格式化的相同句子,以便将单词之间的多个空格替换为单个空白字符。

这是我的程序代码:

squeeze :- get0(C),    % Legge un carattere dallo standard input(anche blank)
           put(C),     % Scrive il carattere sullo standard output
           dorest(C).  % Fà tutto il resto.

dorest(46) :- !.   % 46 è il carattere ASCII per lo stop: tutto completato.

dorest(32) :- !,       % 32 è il carattere ACII per blank, impedisci backtrack
              get(C),  % Legge un carattere dallo standard input (non blank)
              put(C),  % Scrive il carattere sullo standard output
              dorest(C).  % Fà tutto il resto.

dorest(Letter) :- squeeze.

我对它的陈述性阅读和剪辑的使用有一些疑问......如果我的解释是正确的,或者我是否遗漏了什么,你能说我吗?

当我在Prolog Shell中调用 squeeze 谓词时,一切都开始了,所以在逻辑上,我必须验证 squeeze 谓词为TRUE或FALSE ......

squeze 谓词为TRUE,当规则体中的所有内容为TRUE时:它必须读取一个字符(也是空白)并将此字符放在输出上并验证 dorest (C)谓词为TRUE(其中C是读取的字符)

dorest(C)是该计划的核心。

IF C是对应a的ASCII码字符46。 (句号):阻止回溯(程序无法尝试其他最差的规则)并验证 dorest 为true,因此 squeeze 谓词被验证为TRUE且该计划将结束

如果C是ASCII码字符32,它对应一个空白字符:阻止回溯(程序无法尝试其他最差的规则)验证 get 谓词,该谓词将导致跳过所有空白字符,在当前输出流上写入C并验证挤压

如果C是一个常见字符,只需验证挤压(这会在读取字符串时产生类似循环的内容)

所以,在这种情况下,我可以看到CUT操作符的使用!作为一种忽视像IF这样的东西的方法,因为在 dorest 规则之间创建了一个互斥

是对还是我错过了什么?

1 个答案:

答案 0 :(得分:1)

是的,你是对的,确实在这里使用cut来创建一个IF结构。可以使用'->' construct显式重写此代码:

squeeze :- get0(C), put(C), dorest(C).

dorest(C):-
  (  C = 46 -> true ;
     C = 32 -> get(C), put(C), dorest(C) ;
     squeeze
  ).

可以看出,squeezedorest是相互递归的过程。 squeeze执行某项操作,然后调用dorest,它会停止,执行某些操作或调用squeeze

这个程序因此描述了一个循环,它读取用户输入直到遇到一个点,然后回显每个字符,除了对于任何白色空格字符序列,只有它们中的第一个被回显,这使得它看起来像是“挤压”几个连续的空间到一个空间:

9 ?- squeeze.
|: 12 34   56
12 34 56
|: asd  432 123-432   56.
asd 432 123-432 56.

Yes
10 ?- squeeze.
|: 123   43 23   .rewe ew wew ew e
123 43 23 .

Yes

这是操作解释,而非声明解释。 I / O是关于“做”,而不是关于“存在”。这就是为什么我在上面使用“过程”这个词来代替“谓词”。