2017-03-27 17 views
1

私はオペレータ#定義している:私はtrueを返します述語check/1を書きたいPrologで構文エラーを検出する方法はありますか?

valid(X):- integer(X). 
valid(X # Y):- valid(X), valid(Y). 

:私は用語がよく形成されているかどうかを確認するには、次の規則に書かれている

:- op(500, yfx, #). 

をその引数が有効な場合はfalse、そうでない場合はfalse私はこれを書いた:

check(Exp):- catch(valid(Exp), error(syntax_error(_),_), fail), !. 

Expが整形式のときに真を返します。それは非合法であるときしかし、それは構文エラーをキャッチしません:

?- check(5 ## 6). 
ERROR: [Thread pdt_console_client_0_Default Process] Syntax error: Operator expected 
ERROR: [Thread pdt_console_client_0_Default Process] check(5 
ERROR: [Thread pdt_console_client_0_Default Process] ** here ** 
ERROR: [Thread pdt_console_client_0_Default Process] ## 6) . 

私はSWI-Prolog version 7.4.1 for amd64を使用しています。

エラーが発生した場合、構文エラーをキャッチしてcheckをfalseに戻すにはどうすればよいですか?あなたのケースでは

答えて

3

は、問題がcheck/1が唯一の有効なPrologの目標は最初 の場所で入力された場合と呼ばれていることです。

check/1がすでに呼び出されたときにこのように、構文は、それがcheck/1自体の観点から意味を持たないかもしれない場合でも、間違いなく、少なくとも有効なProlog  用語です。構文はない  有効である場合は、プロローグ  トップレベルはすでにさえ  check/1を起動せずに、 エラーが発生します。

したがって、構文の問題をより詳細に制御するには、という用語を自分で読んでください。

これを行うにはいくつかの方法があります。簡単なのはread/1です。たとえば:

 
?- catch(read(X), Error, true). 
|: check(5##6). 

Error = error(syntax_error(operator_expected), stream(user_input, 8, 7, 347)). 

このように、あなたは基本的にあなたのように 問題をより細かく制御できます独自のトップレベルを構築することができます。 read_term/2およびこれに関連するいくつかの関連する述部も参照してください。

ような問題に関連して重要なオプションがvariable_names/1です:あなたが読みやすい バインディングを報告できるように、それは、プロローグ 変数とその原子名前の対応関係が得られます。これはトップレベルの重要な部分であり、ISO標準化における最近の進歩は、そのような機能を非常に助けてくれました。たぶん、適切な時期に、 システムで使用可能な  Prologにポータブルトップレベルを書くことができます。あなたの恩恵を受ける多くのアプリケーションがあります。

関連する問題