2

Say that I want to remove the last element of a list. I can do it with append/3:

append(WithoutLastElement, [_], List)

However, this leaves behind a choicepoint! Try append(X, [_], [1, 2]), for example.

I can write my own predicate (taken from here)

list_butlast([X|Xs], Ys) :-
  list_butlast_prev(Xs, Ys, X).

list_butlast_prev([], [], _).
list_butlast_prev([X1|Xs], [X0|Ys], X0) :-  
  list_butlast_prev(Xs, Ys, X1).

But I wonder if there's a way to use a built-in, the append/3 solution has the advantage of taking about 2 seconds to read and understand what is happening. list_butlast_prev requires a little more thought.

I'm using SWI-Prolog and would appreciate answers which work there, but I'm also curious if it's possible in other Prologs.

false
  • 10,264
  • 13
  • 101
  • 209
num1
  • 4,825
  • 4
  • 31
  • 49
  • 1
    @false, why did you remove the swi-prolog tag? I'm asking specifically about whether it's possible to do this using swi-prolog's library – num1 Jul 11 '18 at 20:00
  • The question is not specific to SWI. You said: *I'm using SWI-Prolog and would appreciate answers which work there, but I'm also curious if it's possible in other Prologs.* So not even you want an answer specific only to SWI. – false Jul 12 '18 at 06:39

1 Answers1

0

How about using append/3 in conjunction with ->/2, i.e.:

(append(WithoutLastElement, [_], List)->true)

For example wrapped in a procedure:

list_butlast(List, ListWithoutLast):-
  (append(ListWithoutLast, [_], List)->true).
gusbro
  • 22,357
  • 35
  • 46