0
votes

I want to implement a predicate (vecLine2BitLine) which does the following: get two lists and a number the first list is the length of blocks (the elements of the blocks are '$') and the second list contains the indexes that these blocks should be placed at meaning:

vecLine2BitLine([1,2,1],[2,5,9],12,BitLine).
BitLine=[' ','$',' ',' ','$','$',' ',' ','$',' ',' ',' ']. 

explanation:a block of length 1 is at index 2 and a block of length 2 is at index 5 and so on..

insert_at_mul : inserts an element N times (it works perfectly,dupli and my_flatten were implemented previously so i used them)

Ive been trying to activate insert_at_mul N times when N is the length of the list X and Y in the predicate vecLine2BitLine.

dupli(L1,N,L2) :- dupli(L1,N,L2,N).
dupli([],_,[],_).
dupli([_|Xs],N,Ys,0) :- dupli(Xs,N,Ys,N).
dupli([X|Xs],N,[X|Ys],K) :- K > 0, K1 is K - 1, dupli([X|Xs],N,Ys,K1).

my_flatten(X,[X]) :- \+ is_list(X).
my_flatten([],[]).
my_flatten([X|Xs],Zs) :- my_flatten(X,Y), my_flatten(Xs,Ys), append(Y,Ys,Zs).

insert_at_mul(L,X,K,R,N):-dupli([X],N,XX) , insert_at(L,XX,K,L1) , my_flatten(L1,R).

get_num_spaces(L,N,X):-sum(L,S), X is N-S.
generate_spaces(N,L,X):- insert_at_mul(L,'',1,X,N).


vecLine2BitLineAux([],[],_,_,_).
vecLine2BitLineAux([X|Tail1],[Y|Tail2],N,L,Lnew):- insert_at_mul(L,'*',Y,Lnew,X) ,vecLine2BitLineAux(Tail1,Tail2,N,Lnew,R). // problem here!!!
vecLine2BitLine(X,Y,N,L):- get_num_spaces(X,N,Z) , generate_spaces(Z,[],ZZ) , vecLine2BitLineAux(X,Y,N,ZZ,L).

now the problem is that in the function vecLine2BitLine i cant activate insert_at_mul N times(thats what i tried to do in this code, but failed).

how can I fix vecLine2BitLine for it to work properly as in returning the correct output by actually activating the predicate insert_at_mul N times?? THANKS! added :

vecLine2BitLine : input parameters : (L1,L2,N,Result) N: after activating the predicate Result will be N in length.

L1: L1 is a list of numbers each number indicates the length of a block, a block is comprised of a Sequence of '$'.

L2: L2 is a list of numbers the numbers are indices for where the blocks in L1 should be placed.

example:

vecLine2BitLine([3,2],[1,5],9,BitLine).

we can look at the input better as tuples :

vecLine2BitLine[(3,1),(2,5)],9,BitLine).

(3,1) : there is a sequence of '' 3 times at index 1 (2,5) : there is a sequence of '' 2 times at index 5 in our example 9 is the length of BitLine at the end and we have to insert into the list BitLine 3+2 of the "special chars" '*' but we have 9-(3+2) places left in the list so we add '' in those places and then we get:

BitLine=['$','$','$','','$','$','','','',''].
1

1 Answers

3
votes

This is kind of a nice problem because you can use the arguments as loop counters. The K argument gets you to the proper index. Let's just traverse the list and find a particular index as an example. Notice the base case is that you're at the right element, and the inductive case is prior to the right element.

traverse(1, [X|_], X).
traverse(N, [_|Xs], X) :- N > 0, N0 is N-1, traverse(N0, Xs, X).

We're going to apply that pattern to insert_at/4 to get to the right location in the list. Now let's write a repeat/3 predicate that repeats X N times in a new list L. This time the base case is when we've added all the repetitions we care to, and the inductive case is that we'll add another instance.

repeat(1, X, [X]).
repeat(N, X, [X|Xs]) :- N > 0, N0 is N-1, repeat(N0, X, Xs).

You can see the similarity of structure between these two. Try to combine them into a single predicate. Since this is homework, I'll stop here. You're inches from the goal.