2014-11-22 76 views
4

我想將通過整數分隔的單詞列表分割成列表列表。序言:整數列表中的整數列表

樣品的查詢和預期的結果:

?- separatewords([h,e,l,l,o,1,o,v,e,r,3,t,h,e,r,e], X). 
X = [[h,e,l,l,o],[o,v,e,r],[t,h,e,r,e]]. 

我已經取得了以下幾件事: 拆分列表進入第一個整​​數前一個列表和一個第一整數後:

樣品查詢與結果:

?- take1word([h,e,l,l,o,1,o,v,e,r,3,t,h,e,r,e], X, Y). 
X = [h,e,l,l,o], Y = [o,v,e,r,3,t,h,e,r,e].     % OK 

我的代碼:

take1word([H|T],[],T) :- 
    integer(H). 
take1word([H|T],[H|Hs],Y) :- 
    ( float(H), take1word(T,Hs,Y) 
    ; atom(H), take1word(T,Hs,Y) 
    ). 

對於分離的話我的代碼如下:

separatewords([],[]). 
separatewords([H|T],L) :- separatewords(T,[take1word([H|T],)|L]). 

只給我false結果,但我不知道,我在做什麼錯。

回答

2

您遇到問題take1word/3:如果列表中有一個整數,但它不會佔用最後一個單詞。你需要另一個基地條款添加到它:

take1word([], [], []). 
take1word([H|T],[],T) :- integer(H). 
take1word([H|T],[H|Hs],Y) :- float(H), take1word(T,Hs,Y); atom(H), take1word(T,Hs,Y). 

現在你separatewords/2將工作:

separatewords([],[]). 
separatewords(L, [W|T]) :- take1word(L,W,R), separatewords(R,T). 

Demo.

+0

工作 - 謝謝! – 2014-11-22 14:54:51

2

這裏是你如何能在邏輯上純的方式進行。

使用splitlistIf/3與通知型測試謂詞integer_t/2串聯!

integer_t(X,Truth) :- integer(X), !, Truth = true. 
integer_t(X,Truth) :- nonvar(X), !, Truth = false. 
integer_t(X,true) :- freeze(X, integer(X)). 
integer_t(X,false) :- freeze(X,\+integer(X)). 

讓我們來看看他們在行動!

 
?- Xs=[ h,e,l,l,o,1,o,v,e,r,3,t,h,e,r,e ], splitlistIf(integer_truth,Xs,Yss). 
Xs = [ h,e,l,l,o,1,o,v,e,r,3,t,h,e,r,e ], 
Yss = [[h,e,l,l,o],[o,v,e,r],[t,h,e,r,e]]. % succeeds deterministically 

由於實現是單調的,所以在使用非基礎條件時可以安全地使用它。

請考慮以下兩個邏輯上等效的查詢:程序上,它們在目標splitListIf(integer_t,Xs,Yss)被證明時在Xs中的物品的實例化方面有所不同。

 
?- Xs = [_,_,_,_,_], Xs = [a,b,0,b,a], splitlistIf(integer_t,Xs,Yss). 
Xs = [a,b,0,b,a], Yss = [[a,b],[b,a]].  % succeeds deterministically 

?- Xs = [_,_,_,_,_], splitlistIf(integer_t,Xs,Yss), Xs = [a,b,0,b,a]. 
    Xs = [a,b,0,b,a], Yss = [[a,b],[b,a]] % succeeds leaving behind choicepoint 
; false. 

執行足夠聰明,只有在必要時纔會留下選擇點。

+0

isInteger是個好名字嗎? – false 2015-05-17 21:03:09

+0

[相關](http://stackoverflow.com/questions/27306453/safer-type-tests-in-prolog)的名稱查找。 – false 2015-05-17 21:22:22

+0

CamelCase不是很Prolog-ish。 'int'不是一個類型。 'integer_truth/2'。提到實例化的狀態('Nonvar')是沒有必要的:沒有約束的實現會相當正確地產生實例化錯誤。 – false 2015-05-18 15:33:16