默认Prolog谓词排序
如果我在数据库中有一个简单的谓词,是否有一种方法可以请求以特定顺序(asc/desc)返回结果,而不必将它们全部读入内存并执行sort/2或set/3 例如,考虑这个数据库:默认Prolog谓词排序,prolog,Prolog,如果我在数据库中有一个简单的谓词,是否有一种方法可以请求以特定顺序(asc/desc)返回结果,而不必将它们全部读入内存并执行sort/2或set/3 例如,考虑这个数据库: animal(dog). animal(cat). animal(elephant). animal(bird). animal(aardvark). 我想在第一个术语中将动物声明为已排序的ASC,以便我可以像下面这样简单地查询它: ?- animal(X). X = aardvark ; X = bird ; X =
animal(dog).
animal(cat).
animal(elephant).
animal(bird).
animal(aardvark).
我想在第一个术语中将动物声明为已排序的ASC,以便我可以像下面这样简单地查询它:
?- animal(X).
X = aardvark ;
X = bird ;
X = cat ;
X = dog ;
X = elephant ;
No.
如果能够做到这一点,将非常方便地将我的知识库更像是一个传统的数据库 不,如果不阅读它们,就无法对它们进行排序 Ofc您可以编写已排序的谓词或生成已排序的谓词:
findall(sorted_animal(X),animal(X),Animals),
sort(Animals,SAnimals),
maplist(assertz(X),SAnimals),
compile_predicates([sorted_animal]/1).
或
但是您必须将谓词animal/1
声明为动态:
:-dynamic(animal/1).
animal(dog).
....
(在代码文件中)
我使用编译谓词/1
来提高速度;但是,这意味着您不能在该谓词上再次使用assert/1
或retract/1
,因此,如果添加/删除动物,请跳过该谓词
或者,您可以将其作为一个参数使用并传递序言,它掩盖了复杂的排序问题,为数据库访问、FIFO或LIFO指定了严格的时间顺序模型,默认为FIFO。这是合理的,因为这种访问定义了计算模型 因此,没有标准的方法来更改子句检索顺序 我认为/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 = >
).
测试结果:
?- test.
aardvark
bird
cat
dog
elephant
/* 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