7

私は次の簡単なコードを書きました。「男性」と書くと、このコードは「男性ですか?」と尋ねられることを期待しています。「いいえ」と入力すると、画面に「彼女は女性です」と表示されます。

male :- ( print('is it male ? '),read(yes)) -> true; asserta( not(male)),female.
female:- not(male),print('she is female').
not(P) :- (call(P) -> fail ; true) .

しかし、このコードには次のエラーがあります:

uncaught exception: error(permission_error(modify,static_procedure,not/1),asserta/1);

swi-prologのエラーは次のとおりです。

ERROR: asserta/1: No permission to modify static_procedure `not/1'
4

1 に答える 1

9

gusbro が言ったように、not/1 は定義済みの静的プロシージャです (したがって、同じ名前を使用することはお勧めできません)。ただし、標準定義を上書きできるため、swi-prolog でエラーが発生する理由はこれではありません。

?- assert(not(42)).
true.

?- not(42).
true.

問題は、コードで既に not/1 を定義しており、述語を動的として明示的に宣言しない場合、swi-prolog はそれが静的であると想定し、変更を許可しないことです。

コードに次の行を挿入することで、動的として宣言できます。

:-dynamic(not/1).

エラーメッセージが示すように、これは他のプロローグ実装(gnu-prologなど)の問題を解決しないと思いますpermission_error(modify,static_procedure,not/1)。いずれにせよ、名前を変更することを強くお勧めします。

ちなみに、引数が何であるかを単純にテストし、対応するメッセージを出力する方が、より簡単でクリーンです。ただし、より複雑なものを作成したい場合 (おそらく状態を使用して)、アサート/リトラクトの方が効率的であるため、グローバル変数を使用できます。

于 2011-12-29T17:36:51.773 に答える