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

Macros 创建自定义枚举的Prolog快捷方式,macros,prolog,Macros,Prolog,我试图通过一系列事实创建一个自定义枚举 greater(X,Y) :- less (Y,X). less(a,b). less(b,c). less(c,d). 大(X,Y):-小(Y,X)。 减(a,b)。 减(b,c)。 减(c,d)。 这很好,但是有大量重复 我正试着把它减下来。有没有一种方法可以通过变换将数组用于简单的线性事实序列 transform([a,b,c,d]) resulting in the same less definitions. 变换([a,b,c,d]) 导致

我试图通过一系列事实创建一个自定义枚举

greater(X,Y) :- less (Y,X). less(a,b). less(b,c). less(c,d). 大(X,Y):-小(Y,X)。 减(a,b)。 减(b,c)。 减(c,d)。 这很好,但是有大量重复

我正试着把它减下来。有没有一种方法可以通过变换将数组用于简单的线性事实序列

transform([a,b,c,d]) resulting in the same less definitions. 变换([a,b,c,d]) 导致相同的定义更少。 我已经创建了一个使用数组和nextto/member函数进行测试的“less”定义,但是我不能像添加单个声明那样添加异常或等效情况。因此,我有兴趣简化简单的案例定义,然后希望用更多的定义来补充它

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

谢谢

编辑:

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]). 我能够使用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). 设置小于([])。 无集合([X,Y | L]):-assert(myless(X,Y)),无集合([Y | L])。 :-set_less([a,b,c,d])。 输出: 目标(指令)失败:用户:无设置([a、b、c、d]) ?上市。 :-动态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]). mylist([a,b,c,d])。 设置小于([])。 设置小于([\])。----钥匙 无集合([X,Y | L]):-assert(myless(X,Y)),无集合([Y | L])。 :-set_less([a,b,c,d])。 真管用!这是定义自定义枚举的好方法吗?我看到它现在可以工作了,谢谢

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

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

或者你想用运营商univ做实验

术语扩展(列表枚举(名称,列表),[mylist(名称,列表)| Flist]):- 列表\枚举\到\列表(列表,列表)。 列表枚举到列表([],[])。 列表\u枚举\u到\u列表([\u],])。 列表枚举到列表([X,Y | Xs],[myless(X,Y)| Ys]):- list_enumerate_to_list([Y | Xs],Ys)。 列举(测试[a1、b1、c1、d1])。 列举(首先,[a,b,c,d])。 列表_枚举(第二,[f,e,g,h])。 无测试(X,Y):-myless(X,Y)。 testless(X,Y):-myless(X,Z),testless(Z,Y)。 输出--------------------------------------------------------------- ?上市。 myless(a1,b1)。 myless(b1,c1)。 myless(c1,d1)。 myless(a,b)。 myless(b,c)。 myless(c,d)。 myless(f,e)。 迈尔斯(e,g)。 myless(g,h)。 -无测试(a1,c1)。 是的; 错。 ?-无测试(X,c1)。 X=b1; X=a1; 错。 真管用!感谢freenode上的soupdragon#prolog


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

如果您想要项目的总顺序,也可以在查阅/编译时将它们映射到自然数。进行比较时,只需查找数字并进行比较。如果你有很多物品,这应该会快很多

大概是这样的:

% 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.

我想我可以在面向数组的版本之前添加它们。我不知道这个=。。接线员@demostenx:可以使set_less/1谓词起作用。追踪目标集合[a,b,c,d]),你会发现它失败了,因为集合[d]失败了。哇!你完全正确,那样会更快。我正在枚举,因为我无法使用预定义类型。这里我唯一关心的是,当我使用多个并行枚举时,可能会发生键冲突。谢谢你的好主意!