1
:- import append/3 from basics.


    help1(0,L,[]).
    help1(_,[],[]).
    help1(N,[X|Xs],[X|Res]):- N2 is N - 1, help1(N2,Xs,Res).

    help2(0,L,L).
    help2(N,[X|Xs],Res):- N2 is N - 1, help2(N2,Xs,Res).


    help3(N,L,R):- help1(N,L,R) append help2(N,L,R).

In the following piece of code my help1 predicate will store the first N values in a list. My help2 predicate will store all the values after the first N values in a list.

Finally in my help3 function i am trying to append the results i get from help1 and help2. But i am not able to do so. Can anyone help me out or point out what mistake i have done?

user1010101
  • 2,062
  • 7
  • 47
  • 76
  • `help1` is commonly called `take` and `help2` is usually called `drop`. Do you have a `trace` predicate in your prolog system? It might help you a lot. – Patrick J. S. Dec 14 '14 at 11:23
  • `help1` is almost right. The second clause produces wrong results. either ensure that the number is greater than `0`, or drop the clause. Your `drop` is fine. I'm getting syntax errors for your `help3`. Prolog is not a functional language, you'll have to call the predicates one after another. `(help3(N,L,R):-help1(N,L,R1),help2(N,L,R2), append(R1,R2,R))`. What is the purpose of `help3` anyway? you could translate that into (`help3(N,X,X):- N >= 0, is_list(X).`) – Patrick J. S. Dec 14 '14 at 11:41
  • Well ultimately i am trying to write a program that rotates all numbers in list N places left. so list [1,2,3,4,5,6,7] N = 3 would look like [4,5,6,7,1,2,3] – user1010101 Dec 14 '14 at 13:37
  • See here: http://stackoverflow.com/questions/16430660/prolog-rotate-list-n-times-right for the opposite (rotating right). Should be trivial to change to rotate left. –  Dec 15 '14 at 10:58

1 Answers1

2

First, the definition of help1 is too general:

?- help1(3,[a,b,c,d,e],Xs).
  Xs = [a,b,c]                   % expected result
; Xs = [a,b,c,d,e]               % WRONG!
; false.

This can be fixed by removing the second clause in the predicate definition:

help1(0,_ ,[]).
help1(_,[],[]) :- false.         % too general
help1(N,[X|Xs],[X|Res]) :- 
   N2 is N-1,
   help1(N2,Xs,Res).

For concatenating two lists, use append/3. Take care of the argument order!

help3(N,L,R) :-
   help1(N,L,R1),
   help2(N,L,R2),
   append(R2,R1,R).

Done! Let's try it:

?- help3(2,[a,b,c,d,e,f],R).
  R = [c,d,e,f,a,b]              % OK! works as expected
; false.

One more thing... actually you don't need to define the auxiliary predicates help1 and help2.

Simply use append/3 and length/2 like this:

help3(N,L,R) :-
   length(Prefix,N),
   append(Prefix,Suffix,L),
   append(Suffix,Prefix,R).

Sample use:

?- help3(2,[a,b,c,d,e,f],R).
R = [c,d,e,f,a,b].
false
  • 10,264
  • 13
  • 101
  • 209
repeat
  • 18,496
  • 4
  • 54
  • 166