Если вы измените is
на =
, как предполагает ответ Дэвида Тонхофера, все это работает.
Но я хотел бы добавить, что вы немного усложняете вещи. Вы правильно определили, что append/3
может использоваться для вычисления префиксов и суффиксов списка. Но для любого списка, подлежащего разбиению, и любого префикса суффикс уникален и уже вычисляется как append/3
! И наоборот: если вы попросите его вычислить суффикс, он также вычислит префикс, который вы ищете. Но затем вы отбрасываете эти ответы и пытаетесь пересчитать соответствующий префикс или суффикс. В этом нет необходимости.
Если мы сделаем ваш префикс и суффикс-предикат немного более явным:
list_prefix_theonlypossiblematchingsuffix(List, Prefix, TheOnlyPossibleMatchingSuffix) :-
append(Prefix, TheOnlyPossibleMatchingSuffix, List).
list_suffix_theonlypossiblematchingprefix(List, Suffix, TheOnlyPossibleMatchingPrefix) :-
append(TheOnlyPossibleMatchingPrefix, Suffix, List).
Мы можем видеть, что, как только у нас есть заданный префикс для списка, на самом деле больше нет выбора для суффикса (и наоборот):
?- list_prefix_theonlypossiblematchingsuffix([a, b, c, d], Prefix, MatchingSuffix).
Prefix = [],
MatchingSuffix = [a, b, c, d] ;
Prefix = [a],
MatchingSuffix = [b, c, d] ;
Prefix = [a, b],
MatchingSuffix = [c, d] ;
Prefix = [a, b, c],
MatchingSuffix = [d] ;
Prefix = [a, b, c, d],
MatchingSuffix = [] ;
false.
Так что нет необходимости пытаться вычислять префикс и суффикс отдельно и сопоставлять их длины. Достаточно ограничить префикс, так как суффикс будет следовать:
partition(List, Prefix, TheOnlyPossibleMatchingSuffix) :-
length(List, N),
PrefixLength is N div 2,
length(Prefix, PrefixLength),
list_prefix_theonlypossiblematchingsuffix(List, Prefix, TheOnlyPossibleMatchingSuffix).
Это работает так, как вы хотите:
?- partition([a, b, c, d], Prefix, Suffix).
Prefix = [a, b],
Suffix = [c, d].
?- partition([a, b, c, d, e], Prefix, Suffix).
Prefix = [a, b],
Suffix = [c, d, e].
Как только вы это сделаете, гораздо яснее заменить цель, включающую list_prefix_verylongpredicatename
с тем, что на самом деле означает:
partition(List, Prefix, Suffix) :-
length(List, N),
PrefixLength is N div 2,
length(Prefix, PrefixLength),
append(Prefix, Suffix, List).
Исходя из других языков программирования, может быть немного необычно, что предикат, такой как append/3
, вычисляет сразу несколько вещей, которые имеют глубокие отношения друг с другом, то есть префикс и уникальный суффикс соответствия. Но это одна из вещей, которая делает Пролог таким выразительным и мощным. Привыкайте к этому и извлекайте из этого прибыль!