質問

I wrote Prolog code for my assignment to drop the nth element of the give list.

I made a predicate called remove/3 which removes an element from the list by its number, and another predicate called drop2/4 which calls the remove/3 predicate by only the numbers who are divisible by N.

But there is a small logical error as it only removes 1 element from the list which is the last element which is divisible by N. I guess this is because when I call the remove/3 predicate with the list L and X it adds all the elements to X then remove element number N, however, L remains the same, so when I call remove/3 again with another N, it doesn't continue on the previous edit, so the previous element which was deleted is restored, so that's why only the last element is deleted.

Query example:

drop([a,b,c,d,e,f,g,h,i,k], 3, X). 

Result should be: X = [a,b,d,e,g,h,k]

drop(L, N, X):-
    drop2(L, N, X, N).

drop2(_, _, _, 1).

drop2(L, N, X, C):-
    N mod C =:= 0,
    remove(L, N, X),
    Z is C-1,
    drop2(L, N, X, Z).

drop2(L, N, X, C):-
    Z is C-1,
    drop2(L, N, X, Z).

remove([_|T], 1, T).
remove([H|T1], N, [H|T2]):-
    N > 1,
    Z is N - 1,
    remove(T1, Z, T2).
役に立ちましたか?

解決

That seems complicated to me. You could just say

drop(Xs,N,Rs) :-
  integer(N) ,
  N > 0 ,
  drop(Xs,1,N,Rs)
  .

where your helper predicate drop/4 is

drop( []     , _ , _ , [] ) .
drop( [X|Xs] , P , N , Rs ) :-
  ( 0 =:= P mod N -> R1 = Rs ; [X|R1] = Rs ) ,
  P1 is P+1 ,
  drop(Xs,P1,N,R1)
  .

or the equivalent

drop( []     , _ , _ , [] ) .
drop( [X|Xs] , P , N , [X|Rs] ) :- 0 =\= P mod N , P1 is P+1 , drop(Xs,P1,N,Rs) .
drop( [_|Xs] , P , N ,    Rs  ) :- 0 =:= P mod N , P1 is P+1 , drop(Xs,P1,N,Rs) .

or even

drop( []     , _ , _ , []     ) .
drop( [_|Xs] , P , P ,    Rs  ) :-         P1 is   1 , drop(Xs,P1,N,Rs) .
drop( [X|Xs] , P , N , [X|Rs] ) :- P < N , P1 is P+1 , drop(Xs,P1,N,Rs) .

他のヒント

No need for writing recursive code... simply use append/3, length/2, and same_length/2!

list_nth1_dropped(As,N1,Bs) :-
   same_length(As,[_|Bs]),
   append(Prefix,[_|Suffix],As),
   length([_|Prefix],N1),
   append(Prefix,Suffix,Bs).

Here's the query the OP gave:

?- Xs = [a,b,c,d,e,f,g,h,i,k],
   list_nth1_dropped(Xs,3,Ys).
  Xs = [a,b,c,d,e,f,g,h,i,k],
  Ys = [a,b,  d,e,f,g,h,i,k]
; false.

How about a more general query?

?- list_nth1_dropped([a,b,c,d,e,f],N,Xs).
  N = 1, Xs = [  b,c,d,e,f]
; N = 2, Xs = [a,  c,d,e,f]
; N = 3, Xs = [a,b,  d,e,f]
; N = 4, Xs = [a,b,c,  e,f]
; N = 5, Xs = [a,b,c,d,  f]
; N = 6, Xs = [a,b,c,d,e  ]
; false.
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top