paths_and_fragments(Expr, [], [], [], [Expr]).
paths_and_fragments(Expr, [], C, [], Fragments) :-
constant_fragments(Expr, C, Fragments).
paths_and_fragments(Expr, [Sub], [], Paths, Fragments) :-
% Here we only have a linear sub-path, so no new paths are generated.
unwrapped_b(Sub, SubExpr, SubSubs, SubConstants),
paths_and_fragments(SubExpr, SubSubs, SubConstants, Paths, SubFragments),
% Need to add the expression to all of the fragments.
maplist(couple_fragment(Expr), SubFragments, Fragments).
paths_and_fragments(Expr, [Sub1W, Sub2W | Subs], Constants, Paths, Fragments) :-
% Here we have multiple sub-paths so we need to actually generate new paths.
% Idea is to get all paths and fragments, then join their fragments over the root.
sub_paths_and_fragments(Expr, [Sub1W, Sub2W | Subs], SubPaths, SubFragments),
joined_sub_paths(Expr, SubFragments, NewPaths),
% Consider constants if necessary.
(Constants \= [] ->
paths_and_fragments(Expr, [], Constants, _, CFragments)
;
CFragments = []
),
% Note: SubFragments is list of lists.
append([CFragments | SubFragments], Fragments),
append(SubPaths, NewPaths, Paths).