Нахождение всех объединений в прологе

Я написал свой первый простой код на PROLOG:

is_beginning([], _).
is_beginning([FirstLetterB|RestWordB], [FirstLetterW|RestWordW]) :-
   FirstLetterB == FirstLetterW,
   is_beginning(RestWordB, RestWordW).

Он предназначен для того, чтобы выяснить, равен ли первый аргумент is_beginning второму началу. Ну, ИМХО, он может довольно хорошо отвечать на вопросы, но теперь мне интересно, есть ли возможность получить все возможные ответы для определенного второго аргумента. например. за

is_beginning(Answers, [a,b,c]);

я хочу получить [], [a], [a,b], [a,b,c] в качестве унификации ответов, но я получаю только [] (самый простой ответ).

Есть ли возможность получить то, что я хочу? Может, в моем определении что-то не так? Я уже пытался использовать findall и forall, но у меня это не работает :(

Спасибо за все ответы.


person Yester    schedule 10.12.2012    source источник
comment
Кстати, второе правило можно немного упростить. Вместо явного написания ограничения равенства вы можете сделать это неявно, повторно используя ту же переменную: is_beginning([X|A],[X|B]):-is_beginning(A,B).   -  person Nick Barnes    schedule 10.12.2012


Ответы (2)


вы используете (==)/ 2, когда не требуется (обратите внимание на комментарий в конце страницы документации). Действительно, если вы измените его на «простую» унификацию (=)/2, ваша программа будет работать так, как вы ожидаете:

is_beginning([], _).
is_beginning([FirstLetterB|RestWordB], [FirstLetterW|RestWordW]) :-
    FirstLetterB = FirstLetterW,
    is_beginning(RestWordB, RestWordW).

контрольная работа:

?- is_beginning(Answers, [a,b,c]).
Answers = [] ;
Answers = [a] ;
Answers = [a, b] ;
Answers = [a, b, c] ;
false.
person CapelliC    schedule 10.12.2012
comment
Большое спасибо - слишком много С++ :( - person Yester; 10.12.2012

Интерпретатор не будет немедленно возвращать все решения. Когда он вернет [], нажмите ";" чтобы сказать ему продолжить поиск:

?- is_beginning(X, [a,b,c]).
X = [] ;
X = [a] ;
X = [a, b] ;
X = [a, b, c] ;
false.

Если вам нужны все эти решения в виде списка Prolog, а не просто распечатаны в консоли, findall/3 действительно то, что вы ищете:

?- findall(X, is_beginning(X, [a,b,c]), L).
L = [[], [a], [a, b], [a, b, c]].
person Nick Barnes    schedule 10.12.2012
comment
Спасибо за ваш ответ, но я уже попробовал оба ваших решения. Похоже, интерпретатор возвращает только один ответ, но я не уверен, почему. - person Yester; 10.12.2012
comment
@Yester Упс... Пропустил == в вашем правиле. См. ответ CapelliC. - person Nick Barnes; 10.12.2012