2

私はPrologを初めて使用し、理解できないことに遭遇しました。

これは私のコードです:

:- dynamic user/3.
user('id', 'Name', 20).

changeAge(Id, NewAge) :-
   user(Id, Name, _),
   retract(user(Id,_,_)),
   assert(user(Id,Name,NewAge)).

データベース内のユーザー情報を更新するには、 changeAge/2次の 3 つの手順を実行します。

  1. を使用して、正しいレコードを検索しuser/3ます。
  2. を使用して、データベースから一致するレコードを 1 つ削除しますretract/1
  3. を使用して、更新された新しいレコードをデータベースに挿入しますassert/1

これは私のコンソール出力です:

1 ?- user('id', _, Age).
Age = 20.

2 ?- changeAge('id', 25).
true.

3 ?- user('id', _, Age).
Age = 25.

4 ?- changeAge("id", 30).
false.

5 ?- user('id', _, Age).
Age = 25.

二重引用符が私に与えられるのに (行 4) 一重引用符が私に与えるのはなぜですかtrue(行 2 false)?

4

2 に答える 2

4

TL;DR 1 : Prolog の「 ' と ' の違いは何ですか?」という質問に対するこの回答を 読んでください。"。

TL;DR 2 : Prolog フラグdouble_quotesが に設定されている場合、ゴールは成功します。'id' = "id"atom

Prolog フラグ は、次double_quotesを使用して実行時に設定できますset_prolog_flag/2

  • ?- set_prolog_flag(double_quotes, chars).

    ?- 'id' = "id".
    
  • ?- set_prolog_flag(double_quotes, codes).

    ?- 'id' = "id".
    
  • ?- set_prolog_flag(double_quotes, atom).

    ?- 'id' = "id".
    

詳細については、SICStus Prolog のマニュアルページの「リストとしての文字列」を参照してください。

于 2015-12-24T07:31:39.660 に答える
2

一部のユーザーがデータベース内の同じ ID に対して複数のレコードを取得したとします。たとえば、人々が複数の名前を持っている場合など、潜在的な用途がある可能性があるもの... いずれにせよ、この答えはモデリング部分を正しくすることではなく、の技術的側面についてです! YMMV。

:- dynamic(user/3).

init_db :-
   retractall(user(_,_,_)),
   maplist(assert, [user(i,n,1),user(i,n,2),user(i,m,1),user(i,m,2),
                    user(j,n,1),user(j,n,2),user(j,m,1),user(j,m,2)]).

changeAge(Id, NewAge) :-
   user(Id, Name, _),
   retract(user(Id,_,_)),
   assert(user(Id,Name,NewAge)).

データベースを初期化し、「いくつかの年齢を変更」しましょう:-)

?- init_db, (changeAge(i,6) ; changeAge(j,7)), false.
false.

?- findall(user(Id,Name,Age), user(Id,Name,Age), DB).
DB = [user(i,m,6),user(i,m,6),user(i,m,6),user(i,m,6),
      user(j,m,7),user(j,m,7),user(j,m,7),user(j,m,7)].

悪い!in: 8 つの異なるレコード。out: 2 つの異なるレコードで、それぞれの多重度は 4 です。

changeAge/2上記の元の事実を復元してから、少し異なる方法で使用しましょう。

?- init_db, changeAge(_,_), false.
false.

?- findall(user(Id,Name,Age), user(Id,Name,Age), DB).
DB = [user(i,m,_),user(i,m,_),user(i,m,_),user(i,m,_),
      user(j,m,_),user(j,m,_),user(j,m,_),user(j,m,_)].

さらに悪いことに!in: 8 つの異なる地上レコード。out: 2 つの別個の非グラウンド レコード。

結論: に付けられた「取り扱いには注意してください」という警告サインに注意してください。

于 2015-12-25T09:16:53.517 に答える