1

データベースに単純な述語がある場合、結果をすべてメモリに読み込んでsort / 2を実行したり、setofを実行したりせずに、結果を特定の順序(asc / desc)で返すように要求できる方法はありますか? / 3?

たとえば、次のデータベースについて考えてみます。

animal(dog).
animal(cat).
animal(elephant).
animal(bird).
animal(aardvark).

どういうわけか、最初の用語で動物をソートされたASCとして宣言して、次のように簡単にクエリできるようにします。

?- animal(X).
X = aardvark ;
X = bird ;
X = cat ;
X = dog ;
X = elephant ;
No.

それができると、私の知識ベースを従来のデータベースのように扱うのに非常に便利です。

4

2 に答える 2

2

いいえ、読まないと並べ替えることはできません。

多くの場合、ソートされた述語を記述したり、ソートされた述語を生成したりできます。

findall(sorted_animal(X),animal(X),Animals),
sort(Animals,SAnimals),
maplist(assertz(X),SAnimals),
compile_predicates([sorted_animal]/1).

また

findall(animal(X),animal(X),Animals),
sort(Animals, SAnimals),
retractall(animal(X)),
maplist(assertz(X),SAnimals),
compile_predicates([sorted_animal]/1).

ただし、述語animal/1を動的として宣言する必要があります。

:-dynamic(animal/1).
animal(dog).
....

(コードファイル内)

以前compile_predicates/1は速度を改善していました。assert/1ただし、これは、その述語を使用したり、再度使用したりできないことを意味するretract/1ため、動物を追加/削除する場合はスキップしてください。

または、順序集合を使用して引数として渡すこともできます

于 2012-09-05T00:13:08.953 に答える
1

Prologは、複雑な順序付けの問題を詳しく説明し、DBアクセス、FIFO、またはLIFOの厳密な時系列モデルを指示しました。デフォルトはFIFOです。そのようなアクセスが計算モデルを定義するので、それは合理的です。

したがって、句の取得順序を変更する標準的な方法はありません。

そのような機能を導入するためにgoal_expansion /2を使用できると思いますので、プロトタイプを試してみます。しかし、私は何かを使えるようになるかどうかはわかりません。

編集

最初の試みですが、遅い(しかしより単純な)リトラクト/アサートを使用します。

/*  File:    order_by.pl
    Author:  Carlo,,,
    Created: Sep  5 2012
    Purpose: sort fact
*/
:- module(order_by,
      [order_by/2
      ]).

order_by(PredicateIndicator, Argument) :-
    (   PredicateIndicator = Module:Functor/Arity
    ;   PredicateIndicator = Functor/Arity, Module = user
    ),
    length(EmptyArgs, Arity),
    P =.. [Functor|EmptyArgs],
    findall(P, retract(Module:P), L),
    predsort(by_arg(Argument), L, S),
    maplist(assert_in_module(Module), S).

assert_in_module(Module, P) :-
    assertz(Module:P).

by_arg(Argument, Delta, E1, E2) :-
    arg(Argument, E1, A1),
    arg(Argument, E2, A2),
    (   A1 @< A2
    ->  Delta = <
    ;   Delta = >
    ).

テストファイル(私はユーザーモジュールでテストしました)、次のことに注意してください:-動的宣言は必須です:

/*  File:    order_by_test.pl
    Author:  Carlo,,,
    Created: Sep  5 2012
    Purpose:
*/
:- [order_by].
:- dynamic animal/1.

animal(dog).
animal(cat).
animal(elephant).
animal(bird).
animal(aardvark).

test :-
    order_by(animal/1, 1),
    forall(animal(X), writeln(X)).

テスト結果:

?- test.
aardvark
bird
cat
dog
elephant
于 2012-09-05T05:28:41.563 に答える