1

私はいくつかのものを事前計算し、結果をプログラムの最初に事実として保存しようとしています:(簡略化されたコード)

:- dynamic cost/2.
%recipe(Id,Cost)
recipe(1,20).
recipe(2,40).

assert_all :- recipe(Id,Cost), assert(cost(Id,Cost)).

しかし、SICStus Prolog でファイルを参照すると、最初の結果 cost(1,20) のみがアサートされます。

| ?- assert_all.
yes
| ?- cost(Id,Cost).
Id = 1,
Cost = 20 ? ;
no
| ?

しかし、SICStus プロローグ コンソールで assert_all の右側を直接入力すると、両方のコスト/2 ファクトが存在します。

| ?- recipe(Id,Cost), assert(cost(Id,Cost)).
Id = 1,
Cost = 20 ? ;
Id = 2,
Cost = 40 ? ;
no
| ?- cost(Id,Cost).                         
Id = 1,
Cost = 20 ? ;
Id = 2,
Cost = 40 ? ;
no

この動作は非常に紛らわしいと思います。何が起こっているのでしょうか?

4

1 に答える 1

2

afail/0を元の句に入れ、成功する別の句を追加します。

assert_all:- 
  recipe(Id,Cost), 
  assert(cost(Id,Cost)),
  fail.
assert_all.

何が起こっているかというと、あなたが書いた手順は、レシピの最初のコストを主張し、選択ポイントを残したということです。バックトラックすると、最終的には他の事実を主張します (バックトラックする場合は;、Sicstus コンソールを押して別の選択肢を要求したときに発生します)。

この回答の失敗駆動ループは、すべてのソリューションをバックトラックしrecipe/2、そのコストを主張します。次に、2 番目の句が成功します。

于 2016-05-17T19:45:55.427 に答える