2013-11-21 81 views
0

問題陳述: 給出一個包含整數和整數列表的列表。您必須從每個子列表中刪除 ,第1,2n,第4,第8 .. ..等元素。序言 - 刪除子列表中的元素

我的解決方案

domains 
     list=integer* 
     elem=i(integer);l(list) 
     clist=elem* 

predicates 
     modify(list, list, integer, integer) 
     exec(clist, clist) 
clauses 
     modify([], [], _, _). 
     modify([H|T], Mod, I, P):- 
       P=I, 
       !, 
       I1=I+1, 
       P1=P*2, 
       modify(T, Mod, I1, P1). 
     modify([H,T], [H|Mod], I, P):- 
       I1=I+1, 
       modify(T, Mod, I1, P). 

     exec([], []). 
     exec([i(N)|T], [i(N)|LR]):- 
       exec(T, LR). 
     exec([l(L)|T], [l(Mod)|LR]):- 
       modify(L, Mod, 1, 1). 

     do():- 
       exec([i(1),l([1,2,3,4,5,6,7,8,9]),l([1,2,3,4])],X), 
       write(X). 

的問題是,該算法的工作,直到它會從每個子列表中的第一個和第二個元素,但從此之後不會刪除的事情,我不知道我做錯了。

exec predicate用於斷言當前元素是整數還是整數列表,將整數添加到結果中,還是將修改後的列表添加到結果中。

modify predicate修改一個給定的名單,並應去除的2

職位權力的所有元素,我寫了do predicate只是稱其爲目標,以避免我想測試它的每一次寫列表。

回答

1

我認爲你做P1=P*2過於頻繁,那麼你錯配2

連續權力也,你在這裏有一個錯字

modify([H,T], [H|Mod], I, P):- ... 

應該讀

modify([H|T], [H|Mod], I, P):- ... 

我會寫

modify([], [], _). 
modify([_|T], Mod, I):- 
    is_pow2(I), !, % as noted by SQB 
    I1 is I+1, 
    modify(T, Mod, I1). 
modify([H|T], [H|Mod], I):- 
    I1 is I+1, 
    modify(T, Mod, I1). 

爲了保持is_pow2/1簡單,你可以做

is_pow2(1). 
is_pow2(2). 
is_pow2(4). 
is_pow2(8). 
is_pow2(16). 
... 

或使用您的Prolog的算術設施。在SWI-Prolog的一個頭腦簡單的定義可能是

is_pow2(N) :- 
    between(0, 63, L), 
    N is 1 << L. 
+0

因爲你不想回溯到第三次修改,所以我會在第二次修改中添加一個剪切,在is_pow2之後。 – SQB

+0

@SQB:謝謝,我忘了它... – CapelliC

1

其實,你修改的核心是正確的,所以它可能在EXEC問題。以下適用於我:

do_modify(X) :- 
    modify([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18], X, 2). 

modify(Lin, Lout, Base) :- modify(Lin, Lout, Base, 1, 1). 

modify([], [], _, _, _). 
modify([_|T], X, Base, N, Power) :- 
    N = Power, 
    !, 
    P1 is Power * Base, 
    N1 is N + 1, 
    modify(T, X, Base, N1, P1). 
modify([H|T], [H|X], Base, N, Power) :- 
    N1 is N + 1, 
    modify(T, X, Base, N1, Power). 

http://www.compileonline.com/execute_prolog_online.php上測試它。