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