Q)Find all initial segments of the given list [1, 3, 6 ,9, 8]. i.e. [], [1], [1,3],[1,3,6]
I'm stuck on how to construct the recursive call to segments,I know I have to use an append function but not sure how to bring it all together, I have the following code:
append([], L, L).
append([H|L1], L2, [H|L3]):-
append(L1, L2, L3).
segments([],[]).
segments([H|L1],R):-
Note that @gusbro's solution with append/3
as well as @brebs answer work well if the initial list is given, however, both permit also other solutions that are not lists.
?- L = [1|non_list], append(Segment, _, L).
L = [1|non_list], Segment = []
; L = [1|non_list], Segment = [1]
; false.
?- L = non_list, append(Segment, _, L).
L = non_list, Segment = []
; false.
So even non_list
works ; that is a term that is as far remote from a list as possible. Often such extra unwanted generalizations are accepted, in particular if you know that you will never rely upon it. Also this is know as a list prefix of a term.
But if you want to be sure that only lists are considered, use Prolog's dcg-formalism which is the method of choice in many areas.
:- set_prolog_flag(double_quotes, chars). % to make "strings" readable
... --> [] | [_], ... . % any sequence
seq([]) --> [].
seq([E|Es]) --> [E], seq(Es).
segment_of(Xs, Zs) :-
phrase((seq(Xs), ...), Zs).
?- segment_of(Xs, "abc").
Xs = []
; Xs = "a"
; Xs = "ab"
; Xs = "abc"
; false.
?- segment_of(Xs, non_list).
false.
?- segment_of("ab", L).
L = "ab"
; L = [a,b,_A]
; L = [a,b,_A,_B]
; L = [a,b,_A,_B,_C]
; ... .