Prolog创建自定义枚举的快捷方式

时间:2010-01-14 12:26:12

标签: macros prolog

我正在尝试通过一系列事实创建自定义枚举。

greater(X,Y) :- less (Y,X).

less(a,b).
less(b,c).
less(c,d).

这很好用,但重复次数很多。

我正试图减少它。有没有办法通过转换将数组用于简单的线性系列事实?

transform([a,b,c,d])

resulting in the same less definitions.

我已经创建了一个“less”定义,它使用数组和nextto / member函数来测试,但是我不能像个别声明一样添加异常或等效的情况。因此,我有兴趣简化简单的案例定义,然后希望用更多的定义来补充它。

这让我想起了lisp中defmacro的用处。

感谢。

修改

我能够使用assert生成一个系列。它成功定义了所有内容,但返回错误。我觉得这不是正确的方法。

set_less([]).
set_less([X,Y|L]):- assert( myless(X,Y) ) , set_less([Y|L]).
:- set_less([a,b,c,d]).

Output: 
Goal (directive) failed: user:set_less([a, b, c, d])

?- listing.

:- dynamic myless/2.

myless(a, b).
myless(b, c).
myless(c, d).

第二次修改:

mylist([a,b,c,d]).

set_less([]).
set_less([_]).  ----- Key!
set_less([X,Y|L]):- assert( myless(X,Y) ) , set_less([Y|L]).
:- set_less([a,b,c,d]).

这确实有效!这是定义自定义枚举的好方法吗?我觉得它现在有用了,谢谢!

3 个答案:

答案 0 :(得分:2)

term_expansion(list_enumerate(Name,List), [mylist(Name,List)|Flist]) :-
    list_enumerate_to_list(List, Flist).

list_enumerate_to_list([], []).
list_enumerate_to_list([_], []).
list_enumerate_to_list([X,Y|Xs], [myless(X,Y)|Ys]) :-
        list_enumerate_to_list([Y|Xs], Ys).

list_enumerate(test,[a1,b1,c1,d1]).
list_enumerate(first,[a,b,c,d]).
list_enumerate(second,[f,e,g,h]).

testless(X,Y) :- myless(X,Y).
testless(X,Y) :- myless(X,Z) , testless(Z,Y).

Output---------------------------------------------------------------

?- listing.


myless(a1, b1).
myless(b1, c1).
myless(c1, d1).
myless(a, b).
myless(b, c).
myless(c, d).
myless(f, e).
myless(e, g).
myless(g, h).

?- testless(a1,c1).
true ;
false.

?- testless(X,c1).
X = b1 ;
X = a1 ;
false.

有效!感谢freenode上的#prolog上的汤龙。

启动时会有一些警告,但可以忽略它们。

答案 1 :(得分:1)

我已经创建了一个使用数组和nextto / member函数进行测试的“less”定义,但是我不能像个别声明一样添加异常或等效案例。

您仍然可以在“数组定义”之前添加“异常和等效案例”,就像在一系列事实之前添加它们一样,不是吗?

或许你想尝试使用=..运算符univ。

答案 2 :(得分:1)

如果您想要物品的总订单,那么您也可以在咨询/编译时将它们映射到自然数。在进行比较时,只需查看数字并进行比较即可。如果你有很多物品,这应该会快得多。

这样的事情:

% Key generation
make_keys(List, Keys) :-
    make_keys(List, 0, Keys).

make_keys([], _, []).
make_keys([El | Els], Index, [mykey(El, Index) | Ks]) :-
    NewIndex is Index + 1,
    make_keys(Els, NewIndex, Ks).

% Mapping ordering/1 to a set of mykey/2
term_expansion(ordering(List), Clauses) :-
    make_keys(List, Clauses).

% Ordering
ordering([first, second, third, fourth, fifth]).

% Comparison by looking at the keys
greater_than(X, Y) :-
    mykey(X, XK),
    mykey(Y, YK),
    XK > YK.