0

When given some input list, I want to build a new list and it should:

  • Always add h in front of the new list
  • Compare every two consecutive elements of the input list, and, if they are equal, append y to the new list, if not, append x.

Example:

?- control([a,a,b,b],R).
R = [h,y,x,y].

Here is my code so far:

control([H,H|T],K,[K,0|T2]):- control([H|T],[K,0],T2).
control([H,J|T],K,[K,1|T2]):- control([J|T],[K,1],T2).
control([H],G,G).

But it is not working correctly.

?-  control([a,a,b,b],[h],L).
L = [[h], 0, [[h], 0], 1, [[[h], 0], 1], 0, [[[...]|...], 1], 0] ;
L = [[h], 0, [[h], 0], 1, [[[h], 0], 1], 1, [[[...]|...], 1], 1] ;
L = [[h], 1, [[h], 1], 1, [[[h], 1], 1], 0, [[[...]|...], 1], 0] ;
L = [[h], 1, [[h], 1], 1, [[[h], 1], 1], 1, [[[...]|...], 1], 1] ;
false.

How can I make it correct?

repeat
  • 18,496
  • 4
  • 54
  • 166
mrnard
  • 21
  • 1
  • 3
  • 2
    Please give examples how you expect this to work. – false May 22 '16 at 14:53
  • 2
    So just pretend it works and show how you would use it. – false May 22 '16 at 14:57
  • Now I have some improvement, here is my new code. karama([H,H|T],[0|L]) :- karama([H|T],L). karama([H,J|T],[1|L]) :- karama([J|T],L). karama([H],[]). init(A,Xs,[A|L]) :- karama(Xs,L). Now it gives me ?- init(1,[1,1,0,0],M). M = [1, 0, 1, 0] ; M = [1, 0, 1, 1] ; M = [1, 1, 1, 0] ; M = [1, 1, 1, 1] ; false. But I want only first one to occur – mrnard May 22 '16 at 15:33
  • 2
    You can edit your question! And show the **exact** result you expect. Don't describe it, your wording is too ambiguous. – false May 22 '16 at 15:38

2 Answers2

4

Here's another way you could take... Based on if_/3 and (=)/3 define list_hxys/2:

list_hxys([E|Es], [h|Xs]) :-
   list_hxys_prev(Es, Xs, E).

list_hxys_prev([], [], _).
list_hxys_prev([E|Es], [X|Xs], E0) :-
   if_(E = E0, X = y, X = x),
   list_hxys_prev(Es, Xs, E).

Some sample queries using SICStus Prolog 4.3.2:

| ?- list_hxys([a,a,b,b], Xs).         % (query given by the OP)
Xs = [h,y,x,y] ? ;                     % expected answer
no
| ?- list_hxys(As, [h,y,x,y]).         % works the "other" way around, too
As = [_A,_A,_B,_B],
prolog:dif(_B,_A) ? ;                  % answer with residual goal dif/2
no
Community
  • 1
  • 1
repeat
  • 18,496
  • 4
  • 54
  • 166
0

Let's break it down:

% Two elements being read are the same -> add y
control([H,H|T],[y|R]) :- control([H|T],R).

% Two elements being read are not the same -> add x
control([H1,H2|T],[x|R]) :- H1 \== H2, control([H2|T],R).

In both clauses we make a recursive call with all but the first checked element and respectively add an 'x' or 'y' to the result.

Now it's up to you to define the base case, note however that depending on whether input lists have an even or uneven amount of elements, two base cases will be required: one for a list with a single element and one for an empty list.

SND
  • 1,552
  • 2
  • 16
  • 29