1
votes

I'm new to Prolog and I'm trying to get my head around lists. The problem I'm struggling with is: Given numbers in the form of lists (1 : [x], 3: [x, x, x]), implement the 'times' predicate /3. E.g.: times([x, x], [x, x, x], R). R = [x, x, x, x, x, x].

The plus, and successor predicates where 2 previous points of the exercise. I know I'm not using the successor predicate, but it didn't seem that useful later on.

This is what i've tried so far

successor([], [x]).
successor([X|T], R) :- 
    append([X|T], [X], R).

plus(L1, L2, R) :- append(L1, L2, R).

times([], _, []).
times(_, [], []).
times([_], L, L).
times(L, [_], L).
times([_|T], L2, R) :- plus(L2, R, RN),
    times(T, L2, RN).

The output is: R is [].

1
What are you trying to do here with append([X|T], [X], R)? - Willem Van Onsem
successor([x, x], R) should produce R = [x, x, x]. So i'm just adding 1 more element just like the Head from the first list. - Cosmin Stoian

1 Answers

1
votes

I think you make things too complicated here. You can define successor as:

successor(T, [x|T]).

We can define plus/3 as:

plus([], T, T).
plus([x|R], S, [x|T]) :-
    plus(R, S, T).

This is more or less the implementation of append/3, except that here we check if the first list only contains x.

For times/3 we know that if the first item is empty, the result is empty:

times([], _, []).

and for a times/3 where the first item has shape [x|R], we need to add the second item to the result of a call to times/3 with R:

times([x|R], S, T) :-
    times(R, S, T1),
    plus(S, T1, T).

So putting it all together, we obtain:

successor(T, [x|T]).

plus([], T, T).
plus([x|R], S, [x|T]) :-
    plus(R, S, T).

times([], _, []).
times([x|R], S, T) :-
    times(R, S, T1),
    plus(S, T1, T).