0
votes

Define a Prolog predicate makelist/3 such that makelist(Start, End, List) is true if List is a list of all integers from the integer Start to the integer End. For example:

makelist(3, 7, [3, 4, 5, 6, 7]) should be true.

Can't understand why my code doesn't work

makelist(H, L, _) :-
    L is H+1.
makelist(H, L, List) :-
    append([], [H], List), H1 is H+1.
makelist(H1, L, List) :-
    append(List, [H1], List1), last(List1, R),
    R \= L+1, makelist(N, L, List1), N is H1+1.
1
Your first clause would immediately succeed if you queried makelist(3, 4, [x,y,z]) for example since 4 is 3+1 would succeed. [x,y,z] could literally be any list, and it would succeed. In your second clause, H1 is evaluated as H + 1 but H1 is never used. Your third clauses uses last/2. Where and how is it defined? - lurker
@lurker last/2 is predefined in SWI- Prolog. I didn't know that either - Shevliaskovic
@Shevliaskovic thanks! I'm always finding new SWI predicates that aren't in GNU. :) - lurker
@user3612140 - Think about the simple (base) case. What does it look like? I would suggest it's the case where H and L are the same. So your base case predicate might be, makelist(H, H, ?) (what would ? look like?). And then think about how you would get to the base case recursively from the general case. - lurker
The last/2 predicate is a library predicate in SWI-Prolog, not a built-in predicate. It's defined in the lists module which, by default, is auto-loaded when a call to one of its predicate is found. - Paulo Moura

1 Answers

1
votes

You can simplify your code, let's take your predicate and examine what is what you really need to do:

% makelist(X,Y,L)

Since your recursive call is increasing by 1 the first parameter, let's call it X, then your base case would be when X is the same than Y:

makelist(X,X,[X]) .

and your recursive call: it will be when X is smaller than Y, you need to increase X and add the value to the list:

makelist(X,Y,[X|L]) :-  X < Y ,
            X1 is X + 1 ,
            makelist(X1, Y, L).