Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Changing elements of a list

Status
Not open for further replies.

jdf442

Programmer
Oct 17, 2010
10
AU
Hey, i am new to this forum so hope i am asking this question in the right spot, sorry if im not!

I just started prolog and am trying to understand lists.

say i have two lists of lists eg:

L1 = [[_,_,_],[_,_,_],[_,_,_].
L2 = [[1,0,5],[8,2,0],[0,0,9]].

how do i compare the two lists of lists so that L1 is replaced by the contents of L2 except if it is a zero (0), then it remains anonymous??

ie: L1 = [[1,_,5],[8,2,_],[_,_,9]].

Any tips would be very helpful, Cheers!
 
First try to do the work on a single list eg :
work_a_list([_,_,_], [1,0,5], X) --> X = [1, _ ,5].

Next if you use SWI-Prolog, you should consider maplist :
maplist:)Goal, ?List)
True if Goal can succesfully be applied on all elements of List.
Arguments are reordered to gain performance as well as to make the
predicate deterministic under normal circumstances.

maplist:)Goal, ?List1, ?List2)
True if Goal can succesfully be applied to all succesive pairs of
elements of List1 and List2.

maplist:)Goal, ?List1, ?List2, ?List3)
True if Goal can succesfully be applied to all succesive triples of
elements of List1..List3.
I you study maplist, you can see it's usefull too for the first problem !
 
ok, thanks for the tips. i have been trying to do it for a single list like you suggested and this is what i have come up with.

work_a_list([],[],[]).
work_a_list([X|L1],[Y|L2],Z) :-
X = 0 -> work_a_list(L1,L2,[Z|X]); work_a_list(L1,L2,[Z|Y]).

where the first argument is the list [1,0,5]
and the second argument is the list [_,_,_]

im not sure what i am doing wrong but it always returns no??
 
If X is an element and Z is a list, then there is no [Z|X]. You can do it the other way around: [X|Z], meaning the same list Z with X appended to it in the beginning

Your mistake is that you never say anything about what Z is. Even if you put the lists right, like [X|Z] and [Y|Z], there is nothing there suggesting what Z should be. By the time the first two lists are [], the third list is something like [1, _, 5] but it doesn't agree with your first rule which states that if the first two lists are [], the third is also [].

My idea of solving it would be something like this:

Code:
work_a_list([X | Lx], [Y | Ly], [Z | Lz]) :-
    % establish a relationship between X, Y and Z and then ...
    work_a_list(Lx, Ly, Lz).

What you need to establish is, for example, if X = 0 then Z = Y and if X \= 0 then Z = X, so there will have to be two cases.

Or you can write a simple predicate that does the establishment between simple values and then use maplist as joel said to extrapolate it to list level.
 
ok, i now understand that you can only add things to the head of a list. I am confused in your example of why you would send just the tail (LZ) of the third list (Z) back to the function and not the whole list? here is what i understand:

1. work_a_list([X|Lx],[Y|Ly],Z) :-
2. X = 0,
3. work_a_list(Lx,Ly,[Y,Z]),
4. X \= 0,
5. work_a_list(Lx,Ly,[X,Z]).

1. is saying that the function will have 3 lists in which X is the head of the first and Lx is the tail of the first, Y is the head of the second and Ly is the tail of the second and Z is an empty list.

2. Checking if X = 0, if it is then execute 3.

3. Add Y (the head of list 2) to the head of the third list and recall the function with the remaing values of list 1 and 2 (Lx and Ly) and the newly formed third list.


4. Checking if X \= 0, if it is then execute 5.

5. Add X (the head of list 2) to the head of the third list and Recall the function with the remaing values of list 1 and 2 (Lx and Ly) and the newly formed third list.

I must not be understanding how lists work? Sorry if it is obvious but i cant get my head around it?
 
Ok, first of all, a variable Z doesn't mean that there is an empty list in there. It just means there can be anything in there, unless you narrow down the possible values of Z by using conditions.

Forget about your steps 1..5, and watch the original code again:

Code:
work_a_list([X | Lx], [Y | Ly], [Z | Lz]) :-
    % establish a relationship between X, Y and Z and then ...
    work_a_list(Lx, Ly, Lz).

This is translated in English like this:

work on lists [X | Lx] and [Y | Ly] gives [Z | Lz] if
there is some relation between X, Y and Z and
work on lists Lx and Ly gives Lz.

Let's read it backwards:

If Lx and Ly and Lz are 3 lists ...
and they satisfy the work_a_list predicate ...
and X and Y and Z are 3 values that satisfy some condition ...
then the lists [X | Lx], [Y | Ly] and [Z | Lz] will also satisfy the work_a_list predicate

The condition that X, Y and Z must satisfy will be something like this:

if X = 0, then Z = Y, else Z = X

So what you need to do is just take my code and replace the comment on the second line with Prolog code that describe the relation between X, Y and Z. I hope I made things clearer for you
 
thanks for the reply,
so i figue the relation ship between X Y and Z is X = 0 -> Z = Y; Z = X; ??

a([X|L1],[Y|L2],[Z|L3]) :-
X = 0 -> Z = Y; Z = X;
a(L1,L2,L3).

when i use this it returns X = (1,_h173).

Im really sorry for bothering you, and i know i must be frustrating you because i cant understand it, im sorry, i just cant get this to work.
 
You got it almost right, only you must enclose the conditional statement in parentheses, because there are some logical ORs there which conflict with the outer logical ANDs

Something like this:
Code:
a([], [], []).
a([X | L1], [Y | L2], [Z | L3]) :-
    (X = 0 -> Z = Y; Z = X),
    a(L1, L2, L3).

And in this case, you should call it like this:

?- a([1, 0, 5], [_, _, _], Result).

I believe it is what you need, only in reverse.
 
Thankyou Kahleen!!!

you help is much appreciated :)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top