0

'_'私の目標は、特定のリスト内の を論理変数に置き換えることです。私のコード:

replace([], []).
replace(['_'|As], [_|Bs]) :- 
    replace(As, Bs).
replace([A|As], [B|Bs]) :-
    A \= '_',
    B = '#',
    replace(As, Bs).

適切なリストを返しますが、常にfalse. 何か助けてください。

4

1 に答える 1

0

に一致する入力はreplace(['_'|As], [_|Bs])、 にも一致しreplace([A|As], [B|Bs])ます。これは、最初の節が実行されている間、後者の節のために選択ポイントが残されていることを意味します。

プロローグが最初の結果を見つけた後、まだ選択ポイントが開いていることに気付くので、さらに結果が必要かどうか尋ねられます。yes と答えた場合、他の句は実行されません。は真ではないため、これは常に失敗しA \= '_'ます。

この動作は間違っていないことに注意してください。「false」は、プログラムが失敗したことを意味するのではなく、既に提示された結果の後に結果が見つからなかったことを意味します。この場合、結果は常に 1 つしかないことがわかっているので、次のようにカット演算子を使用して、選択ポイントを開いたままにしないようにプロローグに指示できます!

replace(['_'|As], [_|Bs]) :- 
    replace(As, Bs), !.

これは本質的に、この句が成功した場合、残りの可能な一致はもはや考慮されるべきではないことをプロローグに伝えます。そのため、選択ポイントが開いたままになることはなく、最初の結果を取得すると、実行が完了し、true が返されます。

于 2014-10-20T07:22:56.873 に答える