2010-01-14 52 views
3

我想通過一系列事實創建自定義枚舉。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. 

我已經創建了一個使用一個陣列和下一步以/成員函數來測試「少」的定義,但是像我可以與個別聲明我不能添加異常或等同例。因此,我希望簡化案例定義的簡化,然後再用更多的定義來補充它。

這讓我想起了lisp中的defmacro在哪裏有用。

謝謝。

編輯:

我能夠生成使用斷言一個系列。它成功定義了一切,但返回一個錯誤。我覺得這不是正確的方法。

 
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]). 

但這工作!這是定義自定義枚舉的好方法嗎?我現在看到它的作品,謝謝!

+0

@demosthenex:您set_less/1謂詞可以作出努力。跟蹤set_less([a,b,c,d])的目標,你會發現它失敗了,因爲set_less([d])失敗。 – Nelson 2010-01-14 21:46:04

回答

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

我已經創建了一個使用數組和nextto/member函數進行測試的「less」定義,但是我無法添加異常或類似的情況,就像我可以使用單個聲明一樣。

您仍然可以在「數組定義」之前添加「異常和等價事例」,就像在一系列事實之前添加它們一樣,對嗎?

或者您可能想要使用univ,=..運算符進行實驗。

+0

我想我可以在面向陣列的版本之前添加它們。我不知道= ..算子! – Demosthenex 2010-01-14 13:39:20

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. 
+0

哇!你絕對正確,那會更快。我列舉了因爲我不能使用預定義的類型。我唯一擔心的是當我使用多個並行枚舉時可能發生關鍵衝突。感謝你這麼好的想法! – Demosthenex 2010-01-18 18:10:54

相關問題